Linux 4.1.28
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXhoYGAAoJEN6mb/eXdyzc82MP/0yCx7A52zsa2OwiMp/07+Gl +/wMJqJQgW2xFM4BLtAaPFdPPhW1b7RZy4+E+/xWVgsxOMZpHebBU4NS9D3R5TA0 GlxU7JrRYdHyiYlfsAcde3/2CplHoXemHf5MDUm3keVrMAbNIvc7NYE+vWzYqehB GLWTKn/48+c/pNly8BqF1kaZeSpVZwUTwqqXkhZ/GoU4d+u5BxvPntNRoypyVlMj wG0SXIF/JW4a6pDE8BUgYrlcB4NTgmDD+ZDykW+nzpMxQrREAGI8Pk6OoFraG7aM MIp/19rCxytOJROvE2O84dS7/AC/ou6wQ9BvVjv1udDFF9S83ZhaBsiQ8of8Ipin yN+P5GTD3jNh665FHmCDO3qpDnA8owah38/I/2Cy9T45dz87QlvH/bEvQ0mRv5nb 0fwBLBaXCCbdRmfFGuh9G6Mz/mF4A5aj8VhPLCDNFsXBIkJBnuLRDpyZoRN/pML5 Y61EES90n6Rwe+WvKgRLo2YBkbs9Cc9Su9COr/CkwfCbKEZgQ65CA0DaYxK/OyBe XyObVovImnzC6rRrdNvoFgsbZkR32zNVNjtNjAAYJhUZTUIFV61quhOJdkIQfLoH RYL5CfhkzPV7qocNLuoQeuESigsYfVsdlWmExohjsZyHGiPmTb+gkWjexvILK0WV /rTajzu793hKkEwnfLSo =p3K7 -----END PGP SIGNATURE----- Merge tag 'v4.1.28' into 4.1-1.0.x-imx Linux 4.1.28 * tag 'v4.1.28': (312 commits) Linux 4.1.28 tmpfs: fix regression hang in fallocate undo netfilter: x_tables: introduce and use xt_copy_counters_from_user netfilter: x_tables: do compat validation via translate_table netfilter: x_tables: xt_compat_match_from_user doesn't need a retval netfilter: ip6_tables: simplify translate_compat_table args netfilter: ip_tables: simplify translate_compat_table args netfilter: arp_tables: simplify translate_compat_table args netfilter: x_tables: don't reject valid target size on some architectures netfilter: x_tables: validate all offsets and sizes in a rule netfilter: x_tables: check for bogus target offset netfilter: x_tables: check standard target size too netfilter: x_tables: add compat version of xt_check_entry_offsets netfilter: x_tables: assert minimum target size netfilter: x_tables: kill check_entry helper netfilter: x_tables: add and use xt_check_entry_offsets netfilter: x_tables: validate targets of jumps netfilter: x_tables: don't move to non-existent next rule netfilter: x_tables: fix unconditional helper netfilter: x_tables: make sure e->next_offset covers remaining blob size ... Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>wifi-calibration
commit
00850640da
|
@ -263,19 +263,23 @@ scmd->allowed.
|
|||
|
||||
3. scmd recovered
|
||||
ACTION: scsi_eh_finish_cmd() is invoked to EH-finish scmd
|
||||
- shost->host_failed--
|
||||
- clear scmd->eh_eflags
|
||||
- scsi_setup_cmd_retry()
|
||||
- move from local eh_work_q to local eh_done_q
|
||||
LOCKING: none
|
||||
CONCURRENCY: at most one thread per separate eh_work_q to
|
||||
keep queue manipulation lockless
|
||||
|
||||
4. EH completes
|
||||
ACTION: scsi_eh_flush_done_q() retries scmds or notifies upper
|
||||
layer of failure.
|
||||
layer of failure. May be called concurrently but must have
|
||||
a no more than one thread per separate eh_work_q to
|
||||
manipulate the queue locklessly
|
||||
- scmd is removed from eh_done_q and scmd->eh_entry is cleared
|
||||
- if retry is necessary, scmd is requeued using
|
||||
scsi_queue_insert()
|
||||
- otherwise, scsi_finish_command() is invoked for scmd
|
||||
- zero shost->host_failed
|
||||
LOCKING: queue or finish function performs appropriate locking
|
||||
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ Currently, these files are in /proc/sys/fs:
|
|||
- nr_open
|
||||
- overflowuid
|
||||
- overflowgid
|
||||
- pipe-user-pages-hard
|
||||
- pipe-user-pages-soft
|
||||
- protected_hardlinks
|
||||
- protected_symlinks
|
||||
- suid_dumpable
|
||||
|
@ -159,6 +161,27 @@ The default is 65534.
|
|||
|
||||
==============================================================
|
||||
|
||||
pipe-user-pages-hard:
|
||||
|
||||
Maximum total number of pages a non-privileged user may allocate for pipes.
|
||||
Once this limit is reached, no new pipes may be allocated until usage goes
|
||||
below the limit again. When set to 0, no limit is applied, which is the default
|
||||
setting.
|
||||
|
||||
==============================================================
|
||||
|
||||
pipe-user-pages-soft:
|
||||
|
||||
Maximum total number of pages a non-privileged user may allocate for pipes
|
||||
before the pipe size gets limited to a single page. Once this limit is reached,
|
||||
new pipes will be limited to a single page in size for this user in order to
|
||||
limit total memory usage, and trying to increase them using fcntl() will be
|
||||
denied until usage goes below the limit again. The default value allows to
|
||||
allocate up to 1024 pipes at their default size. When set to 0, no limit is
|
||||
applied.
|
||||
|
||||
==============================================================
|
||||
|
||||
protected_hardlinks:
|
||||
|
||||
A long-standing class of security issues is the hardlink-based
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 26
|
||||
SUBLEVEL = 28
|
||||
EXTRAVERSION =
|
||||
NAME = Series 4800
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ cflags-$(atleast_gcc44) += -fsection-anchors
|
|||
cflags-$(CONFIG_ARC_HAS_LLSC) += -mlock
|
||||
cflags-$(CONFIG_ARC_HAS_SWAPE) += -mswape
|
||||
cflags-$(CONFIG_ARC_HAS_RTSC) += -mrtsc
|
||||
cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables
|
||||
|
||||
# By default gcc 4.8 generates dwarf4 which kernel unwinder can't grok
|
||||
ifeq ($(atleast_gcc48),y)
|
||||
|
|
|
@ -144,7 +144,7 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs,
|
|||
* prelogue is setup (callee regs saved and then fp set and not other
|
||||
* way around
|
||||
*/
|
||||
pr_warn("CONFIG_ARC_DW2_UNWIND needs to be enabled\n");
|
||||
pr_warn_once("CONFIG_ARC_DW2_UNWIND needs to be enabled\n");
|
||||
return 0;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -164,6 +164,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
|
|||
|
||||
#define pmd_large(pmd) (pmd_val(pmd) & 2)
|
||||
#define pmd_bad(pmd) (pmd_val(pmd) & 2)
|
||||
#define pmd_present(pmd) (pmd_val(pmd))
|
||||
|
||||
#define copy_pmd(pmdpd,pmdps) \
|
||||
do { \
|
||||
|
|
|
@ -212,6 +212,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
|
|||
: !!(pmd_val(pmd) & (val)))
|
||||
#define pmd_isclear(pmd, val) (!(pmd_val(pmd) & (val)))
|
||||
|
||||
#define pmd_present(pmd) (pmd_isset((pmd), L_PMD_SECT_VALID))
|
||||
#define pmd_young(pmd) (pmd_isset((pmd), PMD_SECT_AF))
|
||||
#define pte_special(pte) (pte_isset((pte), L_PTE_SPECIAL))
|
||||
static inline pte_t pte_mkspecial(pte_t pte)
|
||||
|
@ -257,10 +258,10 @@ PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
|
|||
#define pfn_pmd(pfn,prot) (__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
|
||||
#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
|
||||
|
||||
/* represent a notpresent pmd by zero, this is used by pmdp_invalidate */
|
||||
/* represent a notpresent pmd by faulting entry, this is used by pmdp_invalidate */
|
||||
static inline pmd_t pmd_mknotpresent(pmd_t pmd)
|
||||
{
|
||||
return __pmd(0);
|
||||
return __pmd(pmd_val(pmd) & ~L_PMD_SECT_VALID);
|
||||
}
|
||||
|
||||
static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
|
||||
|
|
|
@ -182,7 +182,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
|
|||
#define pgd_offset_k(addr) pgd_offset(&init_mm, addr)
|
||||
|
||||
#define pmd_none(pmd) (!pmd_val(pmd))
|
||||
#define pmd_present(pmd) (pmd_val(pmd))
|
||||
|
||||
static inline pte_t *pmd_page_vaddr(pmd_t pmd)
|
||||
{
|
||||
|
|
|
@ -733,8 +733,8 @@ static int vfp_set(struct task_struct *target,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
vfp_flush_hwstate(thread);
|
||||
thread->vfpstate.hard = new_vfp;
|
||||
vfp_flush_hwstate(thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -257,6 +257,7 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
|
|||
kvm_mmu_free_memory_caches(vcpu);
|
||||
kvm_timer_vcpu_terminate(vcpu);
|
||||
kvm_vgic_vcpu_destroy(vcpu);
|
||||
kvm_vcpu_uninit(vcpu);
|
||||
kmem_cache_free(kvm_vcpu_cache, vcpu);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "pm.h"
|
||||
#include "control.h"
|
||||
#include "common.h"
|
||||
#include "soc.h"
|
||||
|
||||
/* Mach specific information to be recorded in the C-state driver_data */
|
||||
struct omap3_idle_statedata {
|
||||
|
@ -315,6 +316,69 @@ static struct cpuidle_driver omap3_idle_driver = {
|
|||
.safe_state_index = 0,
|
||||
};
|
||||
|
||||
/*
|
||||
* Numbers based on measurements made in October 2009 for PM optimized kernel
|
||||
* with CPU freq enabled on device Nokia N900. Assumes OPP2 (main idle OPP,
|
||||
* and worst case latencies).
|
||||
*/
|
||||
static struct cpuidle_driver omap3430_idle_driver = {
|
||||
.name = "omap3430_idle",
|
||||
.owner = THIS_MODULE,
|
||||
.states = {
|
||||
{
|
||||
.enter = omap3_enter_idle_bm,
|
||||
.exit_latency = 110 + 162,
|
||||
.target_residency = 5,
|
||||
.name = "C1",
|
||||
.desc = "MPU ON + CORE ON",
|
||||
},
|
||||
{
|
||||
.enter = omap3_enter_idle_bm,
|
||||
.exit_latency = 106 + 180,
|
||||
.target_residency = 309,
|
||||
.name = "C2",
|
||||
.desc = "MPU ON + CORE ON",
|
||||
},
|
||||
{
|
||||
.enter = omap3_enter_idle_bm,
|
||||
.exit_latency = 107 + 410,
|
||||
.target_residency = 46057,
|
||||
.name = "C3",
|
||||
.desc = "MPU RET + CORE ON",
|
||||
},
|
||||
{
|
||||
.enter = omap3_enter_idle_bm,
|
||||
.exit_latency = 121 + 3374,
|
||||
.target_residency = 46057,
|
||||
.name = "C4",
|
||||
.desc = "MPU OFF + CORE ON",
|
||||
},
|
||||
{
|
||||
.enter = omap3_enter_idle_bm,
|
||||
.exit_latency = 855 + 1146,
|
||||
.target_residency = 46057,
|
||||
.name = "C5",
|
||||
.desc = "MPU RET + CORE RET",
|
||||
},
|
||||
{
|
||||
.enter = omap3_enter_idle_bm,
|
||||
.exit_latency = 7580 + 4134,
|
||||
.target_residency = 484329,
|
||||
.name = "C6",
|
||||
.desc = "MPU OFF + CORE RET",
|
||||
},
|
||||
{
|
||||
.enter = omap3_enter_idle_bm,
|
||||
.exit_latency = 7505 + 15274,
|
||||
.target_residency = 484329,
|
||||
.name = "C7",
|
||||
.desc = "MPU OFF + CORE OFF",
|
||||
},
|
||||
},
|
||||
.state_count = ARRAY_SIZE(omap3_idle_data),
|
||||
.safe_state_index = 0,
|
||||
};
|
||||
|
||||
/* Public functions */
|
||||
|
||||
/**
|
||||
|
@ -333,5 +397,8 @@ int __init omap3_idle_init(void)
|
|||
if (!mpu_pd || !core_pd || !per_pd || !cam_pd)
|
||||
return -ENODEV;
|
||||
|
||||
return cpuidle_register(&omap3_idle_driver, NULL);
|
||||
if (cpu_is_omap3430())
|
||||
return cpuidle_register(&omap3430_idle_driver, NULL);
|
||||
else
|
||||
return cpuidle_register(&omap3_idle_driver, NULL);
|
||||
}
|
||||
|
|
|
@ -54,12 +54,12 @@ static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev)
|
|||
|
||||
static struct resource s3c64xx_iis0_resource[] = {
|
||||
[0] = DEFINE_RES_MEM(S3C64XX_PA_IIS0, SZ_256),
|
||||
[1] = DEFINE_RES_DMA(DMACH_I2S0_OUT),
|
||||
[2] = DEFINE_RES_DMA(DMACH_I2S0_IN),
|
||||
};
|
||||
|
||||
static struct s3c_audio_pdata i2sv3_pdata = {
|
||||
static struct s3c_audio_pdata i2s0_pdata = {
|
||||
.cfg_gpio = s3c64xx_i2s_cfg_gpio,
|
||||
.dma_playback = DMACH_I2S0_OUT,
|
||||
.dma_capture = DMACH_I2S0_IN,
|
||||
};
|
||||
|
||||
struct platform_device s3c64xx_device_iis0 = {
|
||||
|
@ -68,15 +68,19 @@ struct platform_device s3c64xx_device_iis0 = {
|
|||
.num_resources = ARRAY_SIZE(s3c64xx_iis0_resource),
|
||||
.resource = s3c64xx_iis0_resource,
|
||||
.dev = {
|
||||
.platform_data = &i2sv3_pdata,
|
||||
.platform_data = &i2s0_pdata,
|
||||
},
|
||||
};
|
||||
EXPORT_SYMBOL(s3c64xx_device_iis0);
|
||||
|
||||
static struct resource s3c64xx_iis1_resource[] = {
|
||||
[0] = DEFINE_RES_MEM(S3C64XX_PA_IIS1, SZ_256),
|
||||
[1] = DEFINE_RES_DMA(DMACH_I2S1_OUT),
|
||||
[2] = DEFINE_RES_DMA(DMACH_I2S1_IN),
|
||||
};
|
||||
|
||||
static struct s3c_audio_pdata i2s1_pdata = {
|
||||
.cfg_gpio = s3c64xx_i2s_cfg_gpio,
|
||||
.dma_playback = DMACH_I2S1_OUT,
|
||||
.dma_capture = DMACH_I2S1_IN,
|
||||
};
|
||||
|
||||
struct platform_device s3c64xx_device_iis1 = {
|
||||
|
@ -85,19 +89,19 @@ struct platform_device s3c64xx_device_iis1 = {
|
|||
.num_resources = ARRAY_SIZE(s3c64xx_iis1_resource),
|
||||
.resource = s3c64xx_iis1_resource,
|
||||
.dev = {
|
||||
.platform_data = &i2sv3_pdata,
|
||||
.platform_data = &i2s1_pdata,
|
||||
},
|
||||
};
|
||||
EXPORT_SYMBOL(s3c64xx_device_iis1);
|
||||
|
||||
static struct resource s3c64xx_iisv4_resource[] = {
|
||||
[0] = DEFINE_RES_MEM(S3C64XX_PA_IISV4, SZ_256),
|
||||
[1] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_TX),
|
||||
[2] = DEFINE_RES_DMA(DMACH_HSI_I2SV40_RX),
|
||||
};
|
||||
|
||||
static struct s3c_audio_pdata i2sv4_pdata = {
|
||||
.cfg_gpio = s3c64xx_i2s_cfg_gpio,
|
||||
.dma_playback = DMACH_HSI_I2SV40_TX,
|
||||
.dma_capture = DMACH_HSI_I2SV40_RX,
|
||||
.type = {
|
||||
.i2s = {
|
||||
.quirks = QUIRK_PRI_6CHAN,
|
||||
|
@ -142,12 +146,12 @@ static int s3c64xx_pcm_cfg_gpio(struct platform_device *pdev)
|
|||
|
||||
static struct resource s3c64xx_pcm0_resource[] = {
|
||||
[0] = DEFINE_RES_MEM(S3C64XX_PA_PCM0, SZ_256),
|
||||
[1] = DEFINE_RES_DMA(DMACH_PCM0_TX),
|
||||
[2] = DEFINE_RES_DMA(DMACH_PCM0_RX),
|
||||
};
|
||||
|
||||
static struct s3c_audio_pdata s3c_pcm0_pdata = {
|
||||
.cfg_gpio = s3c64xx_pcm_cfg_gpio,
|
||||
.dma_capture = DMACH_PCM0_RX,
|
||||
.dma_playback = DMACH_PCM0_TX,
|
||||
};
|
||||
|
||||
struct platform_device s3c64xx_device_pcm0 = {
|
||||
|
@ -163,12 +167,12 @@ EXPORT_SYMBOL(s3c64xx_device_pcm0);
|
|||
|
||||
static struct resource s3c64xx_pcm1_resource[] = {
|
||||
[0] = DEFINE_RES_MEM(S3C64XX_PA_PCM1, SZ_256),
|
||||
[1] = DEFINE_RES_DMA(DMACH_PCM1_TX),
|
||||
[2] = DEFINE_RES_DMA(DMACH_PCM1_RX),
|
||||
};
|
||||
|
||||
static struct s3c_audio_pdata s3c_pcm1_pdata = {
|
||||
.cfg_gpio = s3c64xx_pcm_cfg_gpio,
|
||||
.dma_playback = DMACH_PCM1_TX,
|
||||
.dma_capture = DMACH_PCM1_RX,
|
||||
};
|
||||
|
||||
struct platform_device s3c64xx_device_pcm1 = {
|
||||
|
@ -196,13 +200,14 @@ static int s3c64xx_ac97_cfg_gpe(struct platform_device *pdev)
|
|||
|
||||
static struct resource s3c64xx_ac97_resource[] = {
|
||||
[0] = DEFINE_RES_MEM(S3C64XX_PA_AC97, SZ_256),
|
||||
[1] = DEFINE_RES_DMA(DMACH_AC97_PCMOUT),
|
||||
[2] = DEFINE_RES_DMA(DMACH_AC97_PCMIN),
|
||||
[3] = DEFINE_RES_DMA(DMACH_AC97_MICIN),
|
||||
[4] = DEFINE_RES_IRQ(IRQ_AC97),
|
||||
[1] = DEFINE_RES_IRQ(IRQ_AC97),
|
||||
};
|
||||
|
||||
static struct s3c_audio_pdata s3c_ac97_pdata;
|
||||
static struct s3c_audio_pdata s3c_ac97_pdata = {
|
||||
.dma_playback = DMACH_AC97_PCMOUT,
|
||||
.dma_capture = DMACH_AC97_PCMIN,
|
||||
.dma_capture_mic = DMACH_AC97_MICIN,
|
||||
};
|
||||
|
||||
static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32);
|
||||
|
||||
|
|
|
@ -14,38 +14,38 @@
|
|||
#define S3C64XX_DMA_CHAN(name) ((unsigned long)(name))
|
||||
|
||||
/* DMA0/SDMA0 */
|
||||
#define DMACH_UART0 S3C64XX_DMA_CHAN("uart0_tx")
|
||||
#define DMACH_UART0_SRC2 S3C64XX_DMA_CHAN("uart0_rx")
|
||||
#define DMACH_UART1 S3C64XX_DMA_CHAN("uart1_tx")
|
||||
#define DMACH_UART1_SRC2 S3C64XX_DMA_CHAN("uart1_rx")
|
||||
#define DMACH_UART2 S3C64XX_DMA_CHAN("uart2_tx")
|
||||
#define DMACH_UART2_SRC2 S3C64XX_DMA_CHAN("uart2_rx")
|
||||
#define DMACH_UART3 S3C64XX_DMA_CHAN("uart3_tx")
|
||||
#define DMACH_UART3_SRC2 S3C64XX_DMA_CHAN("uart3_rx")
|
||||
#define DMACH_PCM0_TX S3C64XX_DMA_CHAN("pcm0_tx")
|
||||
#define DMACH_PCM0_RX S3C64XX_DMA_CHAN("pcm0_rx")
|
||||
#define DMACH_I2S0_OUT S3C64XX_DMA_CHAN("i2s0_tx")
|
||||
#define DMACH_I2S0_IN S3C64XX_DMA_CHAN("i2s0_rx")
|
||||
#define DMACH_UART0 "uart0_tx"
|
||||
#define DMACH_UART0_SRC2 "uart0_rx"
|
||||
#define DMACH_UART1 "uart1_tx"
|
||||
#define DMACH_UART1_SRC2 "uart1_rx"
|
||||
#define DMACH_UART2 "uart2_tx"
|
||||
#define DMACH_UART2_SRC2 "uart2_rx"
|
||||
#define DMACH_UART3 "uart3_tx"
|
||||
#define DMACH_UART3_SRC2 "uart3_rx"
|
||||
#define DMACH_PCM0_TX "pcm0_tx"
|
||||
#define DMACH_PCM0_RX "pcm0_rx"
|
||||
#define DMACH_I2S0_OUT "i2s0_tx"
|
||||
#define DMACH_I2S0_IN "i2s0_rx"
|
||||
#define DMACH_SPI0_TX S3C64XX_DMA_CHAN("spi0_tx")
|
||||
#define DMACH_SPI0_RX S3C64XX_DMA_CHAN("spi0_rx")
|
||||
#define DMACH_HSI_I2SV40_TX S3C64XX_DMA_CHAN("i2s2_tx")
|
||||
#define DMACH_HSI_I2SV40_RX S3C64XX_DMA_CHAN("i2s2_rx")
|
||||
#define DMACH_HSI_I2SV40_TX "i2s2_tx"
|
||||
#define DMACH_HSI_I2SV40_RX "i2s2_rx"
|
||||
|
||||
/* DMA1/SDMA1 */
|
||||
#define DMACH_PCM1_TX S3C64XX_DMA_CHAN("pcm1_tx")
|
||||
#define DMACH_PCM1_RX S3C64XX_DMA_CHAN("pcm1_rx")
|
||||
#define DMACH_I2S1_OUT S3C64XX_DMA_CHAN("i2s1_tx")
|
||||
#define DMACH_I2S1_IN S3C64XX_DMA_CHAN("i2s1_rx")
|
||||
#define DMACH_PCM1_TX "pcm1_tx"
|
||||
#define DMACH_PCM1_RX "pcm1_rx"
|
||||
#define DMACH_I2S1_OUT "i2s1_tx"
|
||||
#define DMACH_I2S1_IN "i2s1_rx"
|
||||
#define DMACH_SPI1_TX S3C64XX_DMA_CHAN("spi1_tx")
|
||||
#define DMACH_SPI1_RX S3C64XX_DMA_CHAN("spi1_rx")
|
||||
#define DMACH_AC97_PCMOUT S3C64XX_DMA_CHAN("ac97_out")
|
||||
#define DMACH_AC97_PCMIN S3C64XX_DMA_CHAN("ac97_in")
|
||||
#define DMACH_AC97_MICIN S3C64XX_DMA_CHAN("ac97_mic")
|
||||
#define DMACH_PWM S3C64XX_DMA_CHAN("pwm")
|
||||
#define DMACH_IRDA S3C64XX_DMA_CHAN("irda")
|
||||
#define DMACH_EXTERNAL S3C64XX_DMA_CHAN("external")
|
||||
#define DMACH_SECURITY_RX S3C64XX_DMA_CHAN("sec_rx")
|
||||
#define DMACH_SECURITY_TX S3C64XX_DMA_CHAN("sec_tx")
|
||||
#define DMACH_AC97_PCMOUT "ac97_out"
|
||||
#define DMACH_AC97_PCMIN "ac97_in"
|
||||
#define DMACH_AC97_MICIN "ac97_mic"
|
||||
#define DMACH_PWM "pwm"
|
||||
#define DMACH_IRDA "irda"
|
||||
#define DMACH_EXTERNAL "external"
|
||||
#define DMACH_SECURITY_RX "sec_rx"
|
||||
#define DMACH_SECURITY_TX "sec_tx"
|
||||
|
||||
enum dma_ch {
|
||||
DMACH_MAX = 32
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#include <linux/platform_data/usb-ohci-s3c2410.h>
|
||||
#include <plat/usb-phy.h>
|
||||
#include <plat/regs-spi.h>
|
||||
#include <linux/platform_data/asoc-s3c.h>
|
||||
#include <linux/platform_data/spi-s3c64xx.h>
|
||||
|
||||
static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
|
||||
|
@ -74,9 +75,12 @@ static u64 samsung_device_dma_mask = DMA_BIT_MASK(32);
|
|||
static struct resource s3c_ac97_resource[] = {
|
||||
[0] = DEFINE_RES_MEM(S3C2440_PA_AC97, S3C2440_SZ_AC97),
|
||||
[1] = DEFINE_RES_IRQ(IRQ_S3C244X_AC97),
|
||||
[2] = DEFINE_RES_DMA_NAMED(DMACH_PCM_OUT, "PCM out"),
|
||||
[3] = DEFINE_RES_DMA_NAMED(DMACH_PCM_IN, "PCM in"),
|
||||
[4] = DEFINE_RES_DMA_NAMED(DMACH_MIC_IN, "Mic in"),
|
||||
};
|
||||
|
||||
static struct s3c_audio_pdata s3c_ac97_pdata = {
|
||||
.dma_playback = (void *)DMACH_PCM_OUT,
|
||||
.dma_capture = (void *)DMACH_PCM_IN,
|
||||
.dma_capture_mic = (void *)DMACH_MIC_IN,
|
||||
};
|
||||
|
||||
struct platform_device s3c_device_ac97 = {
|
||||
|
@ -87,6 +91,7 @@ struct platform_device s3c_device_ac97 = {
|
|||
.dev = {
|
||||
.dma_mask = &samsung_device_dma_mask,
|
||||
.coherent_dma_mask = DMA_BIT_MASK(32),
|
||||
.platform_data = &s3c_ac97_pdata,
|
||||
}
|
||||
};
|
||||
#endif /* CONFIG_CPU_S3C2440 */
|
||||
|
|
|
@ -74,10 +74,6 @@ void __sync_icache_dcache(pte_t pte, unsigned long addr)
|
|||
{
|
||||
struct page *page = pte_page(pte);
|
||||
|
||||
/* no flushing needed for anonymous pages */
|
||||
if (!page_mapping(page))
|
||||
return;
|
||||
|
||||
if (!test_and_set_bit(PG_dcache_clean, &page->flags)) {
|
||||
__flush_dcache_area(page_address(page),
|
||||
PAGE_SIZE << compound_order(page));
|
||||
|
|
|
@ -370,6 +370,7 @@ struct kvm_mips_tlb {
|
|||
#define KVM_MIPS_GUEST_TLB_SIZE 64
|
||||
struct kvm_vcpu_arch {
|
||||
void *host_ebase, *guest_ebase;
|
||||
int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu);
|
||||
unsigned long host_stack;
|
||||
unsigned long host_gp;
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ extern unsigned int vced_count, vcei_count;
|
|||
* User space process size: 2GB. This is hardcoded into a few places,
|
||||
* so don't change it unless you know what you are doing.
|
||||
*/
|
||||
#define TASK_SIZE 0x7fff8000UL
|
||||
#define TASK_SIZE 0x80000000UL
|
||||
#endif
|
||||
|
||||
#define STACK_TOP_MAX TASK_SIZE
|
||||
|
|
|
@ -686,6 +686,9 @@ static void __init arch_mem_init(char **cmdline_p)
|
|||
for_each_memblock(reserved, reg)
|
||||
if (reg->size != 0)
|
||||
reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
|
||||
|
||||
reserve_bootmem_region(__pa_symbol(&__nosave_begin),
|
||||
__pa_symbol(&__nosave_end)); /* Reserve for hibernation */
|
||||
}
|
||||
|
||||
static void __init resource_init(void)
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#define MIPS_EXC_MAX 12
|
||||
/* XXXSL More to follow */
|
||||
|
||||
extern char __kvm_mips_vcpu_run_end[];
|
||||
extern char mips32_exception[], mips32_exceptionEnd[];
|
||||
extern char mips32_GuestException[], mips32_GuestExceptionEnd[];
|
||||
|
||||
|
|
|
@ -235,6 +235,7 @@ FEXPORT(__kvm_mips_load_k0k1)
|
|||
|
||||
/* Jump to guest */
|
||||
eret
|
||||
EXPORT(__kvm_mips_vcpu_run_end)
|
||||
|
||||
VECTOR(MIPSX(exception), unknown)
|
||||
/* Find out what mode we came from and jump to the proper handler. */
|
||||
|
|
|
@ -312,6 +312,15 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
|
|||
memcpy(gebase + offset, mips32_GuestException,
|
||||
mips32_GuestExceptionEnd - mips32_GuestException);
|
||||
|
||||
#ifdef MODULE
|
||||
offset += mips32_GuestExceptionEnd - mips32_GuestException;
|
||||
memcpy(gebase + offset, (char *)__kvm_mips_vcpu_run,
|
||||
__kvm_mips_vcpu_run_end - (char *)__kvm_mips_vcpu_run);
|
||||
vcpu->arch.vcpu_run = gebase + offset;
|
||||
#else
|
||||
vcpu->arch.vcpu_run = __kvm_mips_vcpu_run;
|
||||
#endif
|
||||
|
||||
/* Invalidate the icache for these ranges */
|
||||
local_flush_icache_range((unsigned long)gebase,
|
||||
(unsigned long)gebase + ALIGN(size, PAGE_SIZE));
|
||||
|
@ -401,7 +410,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|||
/* Disable hardware page table walking while in guest */
|
||||
htw_stop();
|
||||
|
||||
r = __kvm_mips_vcpu_run(run, vcpu);
|
||||
r = vcpu->arch.vcpu_run(run, vcpu);
|
||||
|
||||
/* Re-enable HTW before enabling interrupts */
|
||||
htw_start();
|
||||
|
|
|
@ -666,7 +666,7 @@ void handle_unaligned(struct pt_regs *regs)
|
|||
break;
|
||||
}
|
||||
|
||||
if (modify && R1(regs->iir))
|
||||
if (ret == 0 && modify && R1(regs->iir))
|
||||
regs->gr[R1(regs->iir)] = newbase;
|
||||
|
||||
|
||||
|
@ -677,6 +677,14 @@ void handle_unaligned(struct pt_regs *regs)
|
|||
|
||||
if (ret)
|
||||
{
|
||||
/*
|
||||
* The unaligned handler failed.
|
||||
* If we were called by __get_user() or __put_user() jump
|
||||
* to it's exception fixup handler instead of crashing.
|
||||
*/
|
||||
if (!user_mode(regs) && fixup_exception(regs))
|
||||
return;
|
||||
|
||||
printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
|
||||
die_if_kernel("Unaligned data reference", regs, 28);
|
||||
|
||||
|
|
|
@ -708,7 +708,7 @@
|
|||
#define MMCR0_FCWAIT 0x00000002UL /* freeze counter in WAIT state */
|
||||
#define MMCR0_FCHV 0x00000001UL /* freeze conditions in hypervisor mode */
|
||||
#define SPRN_MMCR1 798
|
||||
#define SPRN_MMCR2 769
|
||||
#define SPRN_MMCR2 785
|
||||
#define SPRN_MMCRA 0x312
|
||||
#define MMCRA_SDSYNC 0x80000000UL /* SDAR synced with SIAR */
|
||||
#define MMCRA_SDAR_DCACHE_MISS 0x40000000UL
|
||||
|
@ -745,13 +745,13 @@
|
|||
#define SPRN_PMC6 792
|
||||
#define SPRN_PMC7 793
|
||||
#define SPRN_PMC8 794
|
||||
#define SPRN_SIAR 780
|
||||
#define SPRN_SDAR 781
|
||||
#define SPRN_SIER 784
|
||||
#define SIER_SIPR 0x2000000 /* Sampled MSR_PR */
|
||||
#define SIER_SIHV 0x1000000 /* Sampled MSR_HV */
|
||||
#define SIER_SIAR_VALID 0x0400000 /* SIAR contents valid */
|
||||
#define SIER_SDAR_VALID 0x0200000 /* SDAR contents valid */
|
||||
#define SPRN_SIAR 796
|
||||
#define SPRN_SDAR 797
|
||||
#define SPRN_TACR 888
|
||||
#define SPRN_TCSCR 889
|
||||
#define SPRN_CSIGR 890
|
||||
|
|
|
@ -1240,6 +1240,16 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
|
|||
current->thread.regs = regs - 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
||||
/*
|
||||
* Clear any transactional state, we're exec()ing. The cause is
|
||||
* not important as there will never be a recheckpoint so it's not
|
||||
* user visible.
|
||||
*/
|
||||
if (MSR_TM_SUSPENDED(mfmsr()))
|
||||
tm_reclaim_current(0);
|
||||
#endif
|
||||
|
||||
memset(regs->gpr, 0, sizeof(regs->gpr));
|
||||
regs->ctr = 0;
|
||||
regs->link = 0;
|
||||
|
|
|
@ -162,11 +162,12 @@ static struct ibm_pa_feature {
|
|||
{0, MMU_FTR_CI_LARGE_PAGE, 0, 0, 1, 2, 0},
|
||||
{CPU_FTR_REAL_LE, 0, PPC_FEATURE_TRUE_LE, 0, 5, 0, 0},
|
||||
/*
|
||||
* If the kernel doesn't support TM (ie. CONFIG_PPC_TRANSACTIONAL_MEM=n),
|
||||
* we don't want to turn on CPU_FTR_TM here, so we use CPU_FTR_TM_COMP
|
||||
* which is 0 if the kernel doesn't support TM.
|
||||
* If the kernel doesn't support TM (ie CONFIG_PPC_TRANSACTIONAL_MEM=n),
|
||||
* we don't want to turn on TM here, so we use the *_COMP versions
|
||||
* which are 0 if the kernel doesn't support TM.
|
||||
*/
|
||||
{CPU_FTR_TM_COMP, 0, 0, 0, 22, 0, 0},
|
||||
{CPU_FTR_TM_COMP, 0, 0,
|
||||
PPC_FEATURE2_HTM_COMP|PPC_FEATURE2_HTM_NOSC_COMP, 22, 0, 0},
|
||||
};
|
||||
|
||||
static void __init scan_features(unsigned long node, const unsigned char *ftrs,
|
||||
|
|
|
@ -647,6 +647,7 @@ unsigned char ibm_architecture_vec[] = {
|
|||
W(0xffff0000), W(0x003e0000), /* POWER6 */
|
||||
W(0xffff0000), W(0x003f0000), /* POWER7 */
|
||||
W(0xffff0000), W(0x004b0000), /* POWER8E */
|
||||
W(0xffff0000), W(0x004c0000), /* POWER8NVL */
|
||||
W(0xffff0000), W(0x004d0000), /* POWER8 */
|
||||
W(0xffffffff), W(0x0f000004), /* all 2.07-compliant */
|
||||
W(0xffffffff), W(0x0f000003), /* all 2.06-compliant */
|
||||
|
@ -709,7 +710,7 @@ unsigned char ibm_architecture_vec[] = {
|
|||
* must match by the macro below. Update the definition if
|
||||
* the structure layout changes.
|
||||
*/
|
||||
#define IBM_ARCH_VEC_NRCORES_OFFSET 125
|
||||
#define IBM_ARCH_VEC_NRCORES_OFFSET 133
|
||||
W(NR_CPUS), /* number of cores supported */
|
||||
0,
|
||||
0,
|
||||
|
|
|
@ -472,13 +472,13 @@ static void hugepd_free(struct mmu_gather *tlb, void *hugepte)
|
|||
{
|
||||
struct hugepd_freelist **batchp;
|
||||
|
||||
batchp = this_cpu_ptr(&hugepd_freelist_cur);
|
||||
batchp = &get_cpu_var(hugepd_freelist_cur);
|
||||
|
||||
if (atomic_read(&tlb->mm->mm_users) < 2 ||
|
||||
cpumask_equal(mm_cpumask(tlb->mm),
|
||||
cpumask_of(smp_processor_id()))) {
|
||||
kmem_cache_free(hugepte_cache, hugepte);
|
||||
put_cpu_var(hugepd_freelist_cur);
|
||||
put_cpu_var(hugepd_freelist_cur);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -623,29 +623,50 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
|
|||
{
|
||||
int config_addr;
|
||||
int ret;
|
||||
/* Waiting 0.2s maximum before skipping configuration */
|
||||
int max_wait = 200;
|
||||
|
||||
/* Figure out the PE address */
|
||||
config_addr = pe->config_addr;
|
||||
if (pe->addr)
|
||||
config_addr = pe->addr;
|
||||
|
||||
/* Use new configure-pe function, if supported */
|
||||
if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
|
||||
ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
|
||||
config_addr, BUID_HI(pe->phb->buid),
|
||||
BUID_LO(pe->phb->buid));
|
||||
} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
|
||||
ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
|
||||
config_addr, BUID_HI(pe->phb->buid),
|
||||
BUID_LO(pe->phb->buid));
|
||||
} else {
|
||||
return -EFAULT;
|
||||
while (max_wait > 0) {
|
||||
/* Use new configure-pe function, if supported */
|
||||
if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
|
||||
ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
|
||||
config_addr, BUID_HI(pe->phb->buid),
|
||||
BUID_LO(pe->phb->buid));
|
||||
} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
|
||||
ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
|
||||
config_addr, BUID_HI(pe->phb->buid),
|
||||
BUID_LO(pe->phb->buid));
|
||||
} else {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* If RTAS returns a delay value that's above 100ms, cut it
|
||||
* down to 100ms in case firmware made a mistake. For more
|
||||
* on how these delay values work see rtas_busy_delay_time
|
||||
*/
|
||||
if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
|
||||
ret <= RTAS_EXTENDED_DELAY_MAX)
|
||||
ret = RTAS_EXTENDED_DELAY_MIN+2;
|
||||
|
||||
max_wait -= rtas_busy_delay_time(ret);
|
||||
|
||||
if (max_wait < 0)
|
||||
break;
|
||||
|
||||
rtas_busy_delay(ret);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
|
||||
__func__, pe->phb->global_number, pe->addr, ret);
|
||||
|
||||
pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
|
||||
__func__, pe->phb->global_number, pe->addr, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ typedef struct {
|
|||
spinlock_t list_lock;
|
||||
struct list_head pgtable_list;
|
||||
struct list_head gmap_list;
|
||||
unsigned long asce_bits;
|
||||
unsigned long asce;
|
||||
unsigned long asce_limit;
|
||||
unsigned long vdso_base;
|
||||
/* The mmu context allocates 4K page tables. */
|
||||
|
|
|
@ -26,12 +26,28 @@ static inline int init_new_context(struct task_struct *tsk,
|
|||
mm->context.has_pgste = 0;
|
||||
mm->context.use_skey = 0;
|
||||
#endif
|
||||
if (mm->context.asce_limit == 0) {
|
||||
switch (mm->context.asce_limit) {
|
||||
case 1UL << 42:
|
||||
/*
|
||||
* forked 3-level task, fall through to set new asce with new
|
||||
* mm->pgd
|
||||
*/
|
||||
case 0:
|
||||
/* context created by exec, set asce limit to 4TB */
|
||||
mm->context.asce_bits = _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION3;
|
||||
mm->context.asce_limit = STACK_TOP_MAX;
|
||||
} else if (mm->context.asce_limit == (1UL << 31)) {
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION3;
|
||||
break;
|
||||
case 1UL << 53:
|
||||
/* forked 4-level task, set new asce with new mm->pgd */
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION2;
|
||||
break;
|
||||
case 1UL << 31:
|
||||
/* forked 2-level compat task, set new asce with new mm->pgd */
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_SEGMENT;
|
||||
/* pgd_alloc() did not increase mm->nr_pmds */
|
||||
mm_inc_nr_pmds(mm);
|
||||
}
|
||||
crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm));
|
||||
|
@ -42,7 +58,7 @@ static inline int init_new_context(struct task_struct *tsk,
|
|||
|
||||
static inline void set_user_asce(struct mm_struct *mm)
|
||||
{
|
||||
S390_lowcore.user_asce = mm->context.asce_bits | __pa(mm->pgd);
|
||||
S390_lowcore.user_asce = mm->context.asce;
|
||||
if (current->thread.mm_segment.ar4)
|
||||
__ctl_load(S390_lowcore.user_asce, 7, 7);
|
||||
set_cpu_flag(CIF_ASCE);
|
||||
|
@ -71,7 +87,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
|
|||
{
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
S390_lowcore.user_asce = next->context.asce_bits | __pa(next->pgd);
|
||||
S390_lowcore.user_asce = next->context.asce;
|
||||
if (prev == next)
|
||||
return;
|
||||
if (MACHINE_HAS_TLB_LC)
|
||||
|
|
|
@ -56,8 +56,8 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm)
|
|||
return _REGION2_ENTRY_EMPTY;
|
||||
}
|
||||
|
||||
int crst_table_upgrade(struct mm_struct *, unsigned long limit);
|
||||
void crst_table_downgrade(struct mm_struct *, unsigned long limit);
|
||||
int crst_table_upgrade(struct mm_struct *);
|
||||
void crst_table_downgrade(struct mm_struct *);
|
||||
|
||||
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
|
||||
{
|
||||
|
|
|
@ -155,7 +155,7 @@ struct stack_frame {
|
|||
regs->psw.mask = PSW_USER_BITS | PSW_MASK_BA; \
|
||||
regs->psw.addr = new_psw | PSW_ADDR_AMODE; \
|
||||
regs->gprs[15] = new_stackp; \
|
||||
crst_table_downgrade(current->mm, 1UL << 31); \
|
||||
crst_table_downgrade(current->mm); \
|
||||
execve_tail(); \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -110,8 +110,7 @@ static inline void __tlb_flush_asce(struct mm_struct *mm, unsigned long asce)
|
|||
static inline void __tlb_flush_kernel(void)
|
||||
{
|
||||
if (MACHINE_HAS_IDTE)
|
||||
__tlb_flush_idte((unsigned long) init_mm.pgd |
|
||||
init_mm.context.asce_bits);
|
||||
__tlb_flush_idte(init_mm.context.asce);
|
||||
else
|
||||
__tlb_flush_global();
|
||||
}
|
||||
|
@ -133,8 +132,7 @@ static inline void __tlb_flush_asce(struct mm_struct *mm, unsigned long asce)
|
|||
static inline void __tlb_flush_kernel(void)
|
||||
{
|
||||
if (MACHINE_HAS_TLB_LC)
|
||||
__tlb_flush_idte_local((unsigned long) init_mm.pgd |
|
||||
init_mm.context.asce_bits);
|
||||
__tlb_flush_idte_local(init_mm.context.asce);
|
||||
else
|
||||
__tlb_flush_local();
|
||||
}
|
||||
|
@ -148,8 +146,7 @@ static inline void __tlb_flush_mm(struct mm_struct * mm)
|
|||
* only ran on the local cpu.
|
||||
*/
|
||||
if (MACHINE_HAS_IDTE && list_empty(&mm->context.gmap_list))
|
||||
__tlb_flush_asce(mm, (unsigned long) mm->pgd |
|
||||
mm->context.asce_bits);
|
||||
__tlb_flush_asce(mm, mm->context.asce);
|
||||
else
|
||||
__tlb_flush_full(mm);
|
||||
}
|
||||
|
|
|
@ -2044,13 +2044,6 @@ void s390_reset_system(void (*fn_pre)(void),
|
|||
S390_lowcore.program_new_psw.addr =
|
||||
PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
|
||||
|
||||
/*
|
||||
* Clear subchannel ID and number to signal new kernel that no CCW or
|
||||
* SCSI IPL has been done (for kexec and kdump)
|
||||
*/
|
||||
S390_lowcore.subchannel_id = 0;
|
||||
S390_lowcore.subchannel_nr = 0;
|
||||
|
||||
/* Store status at absolute zero */
|
||||
store_status();
|
||||
|
||||
|
|
|
@ -112,7 +112,8 @@ void __init paging_init(void)
|
|||
asce_bits = _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH;
|
||||
pgd_type = _REGION3_ENTRY_EMPTY;
|
||||
}
|
||||
S390_lowcore.kernel_asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits;
|
||||
init_mm.context.asce = (__pa(init_mm.pgd) & PAGE_MASK) | asce_bits;
|
||||
S390_lowcore.kernel_asce = init_mm.context.asce;
|
||||
clear_table((unsigned long *) init_mm.pgd, pgd_type,
|
||||
sizeof(unsigned long)*2048);
|
||||
vmem_map_init();
|
||||
|
|
|
@ -184,7 +184,7 @@ int s390_mmap_check(unsigned long addr, unsigned long len, unsigned long flags)
|
|||
if (!(flags & MAP_FIXED))
|
||||
addr = 0;
|
||||
if ((addr + len) >= TASK_SIZE)
|
||||
return crst_table_upgrade(current->mm, 1UL << 53);
|
||||
return crst_table_upgrade(current->mm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -201,7 +201,7 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr,
|
|||
return area;
|
||||
if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) {
|
||||
/* Upgrade the page table to 4 levels and retry. */
|
||||
rc = crst_table_upgrade(mm, 1UL << 53);
|
||||
rc = crst_table_upgrade(mm);
|
||||
if (rc)
|
||||
return (unsigned long) rc;
|
||||
area = arch_get_unmapped_area(filp, addr, len, pgoff, flags);
|
||||
|
@ -223,7 +223,7 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr,
|
|||
return area;
|
||||
if (area == -ENOMEM && !is_compat_task() && TASK_SIZE < (1UL << 53)) {
|
||||
/* Upgrade the page table to 4 levels and retry. */
|
||||
rc = crst_table_upgrade(mm, 1UL << 53);
|
||||
rc = crst_table_upgrade(mm);
|
||||
if (rc)
|
||||
return (unsigned long) rc;
|
||||
area = arch_get_unmapped_area_topdown(filp, addr, len,
|
||||
|
|
|
@ -56,81 +56,52 @@ static void __crst_table_upgrade(void *arg)
|
|||
__tlb_flush_local();
|
||||
}
|
||||
|
||||
int crst_table_upgrade(struct mm_struct *mm, unsigned long limit)
|
||||
int crst_table_upgrade(struct mm_struct *mm)
|
||||
{
|
||||
unsigned long *table, *pgd;
|
||||
unsigned long entry;
|
||||
int flush;
|
||||
|
||||
BUG_ON(limit > (1UL << 53));
|
||||
flush = 0;
|
||||
repeat:
|
||||
/* upgrade should only happen from 3 to 4 levels */
|
||||
BUG_ON(mm->context.asce_limit != (1UL << 42));
|
||||
|
||||
table = crst_table_alloc(mm);
|
||||
if (!table)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_bh(&mm->page_table_lock);
|
||||
if (mm->context.asce_limit < limit) {
|
||||
pgd = (unsigned long *) mm->pgd;
|
||||
if (mm->context.asce_limit <= (1UL << 31)) {
|
||||
entry = _REGION3_ENTRY_EMPTY;
|
||||
mm->context.asce_limit = 1UL << 42;
|
||||
mm->context.asce_bits = _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS |
|
||||
_ASCE_TYPE_REGION3;
|
||||
} else {
|
||||
entry = _REGION2_ENTRY_EMPTY;
|
||||
mm->context.asce_limit = 1UL << 53;
|
||||
mm->context.asce_bits = _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS |
|
||||
_ASCE_TYPE_REGION2;
|
||||
}
|
||||
crst_table_init(table, entry);
|
||||
pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd);
|
||||
mm->pgd = (pgd_t *) table;
|
||||
mm->task_size = mm->context.asce_limit;
|
||||
table = NULL;
|
||||
flush = 1;
|
||||
}
|
||||
pgd = (unsigned long *) mm->pgd;
|
||||
crst_table_init(table, _REGION2_ENTRY_EMPTY);
|
||||
pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd);
|
||||
mm->pgd = (pgd_t *) table;
|
||||
mm->context.asce_limit = 1UL << 53;
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION2;
|
||||
mm->task_size = mm->context.asce_limit;
|
||||
spin_unlock_bh(&mm->page_table_lock);
|
||||
if (table)
|
||||
crst_table_free(mm, table);
|
||||
if (mm->context.asce_limit < limit)
|
||||
goto repeat;
|
||||
if (flush)
|
||||
on_each_cpu(__crst_table_upgrade, mm, 0);
|
||||
|
||||
on_each_cpu(__crst_table_upgrade, mm, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
|
||||
void crst_table_downgrade(struct mm_struct *mm)
|
||||
{
|
||||
pgd_t *pgd;
|
||||
|
||||
/* downgrade should only happen from 3 to 2 levels (compat only) */
|
||||
BUG_ON(mm->context.asce_limit != (1UL << 42));
|
||||
|
||||
if (current->active_mm == mm) {
|
||||
clear_user_asce();
|
||||
__tlb_flush_mm(mm);
|
||||
}
|
||||
while (mm->context.asce_limit > limit) {
|
||||
pgd = mm->pgd;
|
||||
switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) {
|
||||
case _REGION_ENTRY_TYPE_R2:
|
||||
mm->context.asce_limit = 1UL << 42;
|
||||
mm->context.asce_bits = _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS |
|
||||
_ASCE_TYPE_REGION3;
|
||||
break;
|
||||
case _REGION_ENTRY_TYPE_R3:
|
||||
mm->context.asce_limit = 1UL << 31;
|
||||
mm->context.asce_bits = _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS |
|
||||
_ASCE_TYPE_SEGMENT;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN);
|
||||
mm->task_size = mm->context.asce_limit;
|
||||
crst_table_free(mm, (unsigned long *) pgd);
|
||||
}
|
||||
|
||||
pgd = mm->pgd;
|
||||
mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN);
|
||||
mm->context.asce_limit = 1UL << 31;
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_SEGMENT;
|
||||
mm->task_size = mm->context.asce_limit;
|
||||
crst_table_free(mm, (unsigned long *) pgd);
|
||||
|
||||
if (current->active_mm == mm)
|
||||
set_user_asce(mm);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
|
||||
#define PTREGS_OFF (STACK_BIAS + STACKFRAME_SZ)
|
||||
|
||||
#define RTRAP_PSTATE (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
|
||||
#define RTRAP_PSTATE_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
|
||||
#define RTRAP_PSTATE_AG_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
|
||||
|
||||
#define __CHEETAH_ID 0x003e0014
|
||||
#define __JALAPENO_ID 0x003e0016
|
||||
#define __SERRANO_ID 0x003e0022
|
||||
|
|
|
@ -589,8 +589,8 @@ user_rtt_fill_64bit: \
|
|||
restored; \
|
||||
nop; nop; nop; nop; nop; nop; \
|
||||
nop; nop; nop; nop; nop; \
|
||||
ba,a,pt %xcc, user_rtt_fill_fixup; \
|
||||
ba,a,pt %xcc, user_rtt_fill_fixup; \
|
||||
ba,a,pt %xcc, user_rtt_fill_fixup_dax; \
|
||||
ba,a,pt %xcc, user_rtt_fill_fixup_mna; \
|
||||
ba,a,pt %xcc, user_rtt_fill_fixup;
|
||||
|
||||
|
||||
|
@ -652,8 +652,8 @@ user_rtt_fill_32bit: \
|
|||
restored; \
|
||||
nop; nop; nop; nop; nop; \
|
||||
nop; nop; nop; \
|
||||
ba,a,pt %xcc, user_rtt_fill_fixup; \
|
||||
ba,a,pt %xcc, user_rtt_fill_fixup; \
|
||||
ba,a,pt %xcc, user_rtt_fill_fixup_dax; \
|
||||
ba,a,pt %xcc, user_rtt_fill_fixup_mna; \
|
||||
ba,a,pt %xcc, user_rtt_fill_fixup;
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ CFLAGS_REMOVE_perf_event.o := -pg
|
|||
CFLAGS_REMOVE_pcr.o := -pg
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_SPARC64) += urtt_fill.o
|
||||
obj-$(CONFIG_SPARC32) += entry.o wof.o wuf.o
|
||||
obj-$(CONFIG_SPARC32) += etrap_32.o
|
||||
obj-$(CONFIG_SPARC32) += rtrap_32.o
|
||||
|
|
|
@ -214,8 +214,7 @@ do_dcpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
|
|||
subcc %g1, %g2, %g1 ! Next cacheline
|
||||
bge,pt %icc, 1b
|
||||
nop
|
||||
ba,pt %xcc, dcpe_icpe_tl1_common
|
||||
nop
|
||||
ba,a,pt %xcc, dcpe_icpe_tl1_common
|
||||
|
||||
do_dcpe_tl1_fatal:
|
||||
sethi %hi(1f), %g7
|
||||
|
@ -224,8 +223,7 @@ do_dcpe_tl1_fatal:
|
|||
mov 0x2, %o0
|
||||
call cheetah_plus_parity_error
|
||||
add %sp, PTREGS_OFF, %o1
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
.size do_dcpe_tl1,.-do_dcpe_tl1
|
||||
|
||||
.globl do_icpe_tl1
|
||||
|
@ -259,8 +257,7 @@ do_icpe_tl1_nonfatal: /* Ok we may use interrupt globals safely. */
|
|||
subcc %g1, %g2, %g1
|
||||
bge,pt %icc, 1b
|
||||
nop
|
||||
ba,pt %xcc, dcpe_icpe_tl1_common
|
||||
nop
|
||||
ba,a,pt %xcc, dcpe_icpe_tl1_common
|
||||
|
||||
do_icpe_tl1_fatal:
|
||||
sethi %hi(1f), %g7
|
||||
|
@ -269,8 +266,7 @@ do_icpe_tl1_fatal:
|
|||
mov 0x3, %o0
|
||||
call cheetah_plus_parity_error
|
||||
add %sp, PTREGS_OFF, %o1
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
.size do_icpe_tl1,.-do_icpe_tl1
|
||||
|
||||
.type dcpe_icpe_tl1_common,#function
|
||||
|
@ -456,7 +452,7 @@ __cheetah_log_error:
|
|||
cmp %g2, 0x63
|
||||
be c_cee
|
||||
nop
|
||||
ba,pt %xcc, c_deferred
|
||||
ba,a,pt %xcc, c_deferred
|
||||
.size __cheetah_log_error,.-__cheetah_log_error
|
||||
|
||||
/* Cheetah FECC trap handling, we get here from tl{0,1}_fecc
|
||||
|
|
|
@ -948,7 +948,24 @@ linux_syscall_trace:
|
|||
cmp %o0, 0
|
||||
bne 3f
|
||||
mov -ENOSYS, %o0
|
||||
|
||||
/* Syscall tracing can modify the registers. */
|
||||
ld [%sp + STACKFRAME_SZ + PT_G1], %g1
|
||||
sethi %hi(sys_call_table), %l7
|
||||
ld [%sp + STACKFRAME_SZ + PT_I0], %i0
|
||||
or %l7, %lo(sys_call_table), %l7
|
||||
ld [%sp + STACKFRAME_SZ + PT_I1], %i1
|
||||
ld [%sp + STACKFRAME_SZ + PT_I2], %i2
|
||||
ld [%sp + STACKFRAME_SZ + PT_I3], %i3
|
||||
ld [%sp + STACKFRAME_SZ + PT_I4], %i4
|
||||
ld [%sp + STACKFRAME_SZ + PT_I5], %i5
|
||||
cmp %g1, NR_syscalls
|
||||
bgeu 3f
|
||||
mov -ENOSYS, %o0
|
||||
|
||||
sll %g1, 2, %l4
|
||||
mov %i0, %o0
|
||||
ld [%l7 + %l4], %l7
|
||||
mov %i1, %o1
|
||||
mov %i2, %o2
|
||||
mov %i3, %o3
|
||||
|
|
|
@ -100,8 +100,8 @@ do_fpdis:
|
|||
fmuld %f0, %f2, %f26
|
||||
faddd %f0, %f2, %f28
|
||||
fmuld %f0, %f2, %f30
|
||||
b,pt %xcc, fpdis_exit
|
||||
nop
|
||||
ba,a,pt %xcc, fpdis_exit
|
||||
|
||||
2: andcc %g5, FPRS_DU, %g0
|
||||
bne,pt %icc, 3f
|
||||
fzero %f32
|
||||
|
@ -144,8 +144,8 @@ do_fpdis:
|
|||
fmuld %f32, %f34, %f58
|
||||
faddd %f32, %f34, %f60
|
||||
fmuld %f32, %f34, %f62
|
||||
ba,pt %xcc, fpdis_exit
|
||||
nop
|
||||
ba,a,pt %xcc, fpdis_exit
|
||||
|
||||
3: mov SECONDARY_CONTEXT, %g3
|
||||
add %g6, TI_FPREGS, %g1
|
||||
|
||||
|
@ -197,8 +197,7 @@ fpdis_exit2:
|
|||
fp_other_bounce:
|
||||
call do_fpother
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
.size fp_other_bounce,.-fp_other_bounce
|
||||
|
||||
.align 32
|
||||
|
|
|
@ -461,9 +461,8 @@ sun4v_chip_type:
|
|||
subcc %g3, 1, %g3
|
||||
bne,pt %xcc, 41b
|
||||
add %g1, 1, %g1
|
||||
mov SUN4V_CHIP_SPARC64X, %g4
|
||||
ba,pt %xcc, 5f
|
||||
nop
|
||||
mov SUN4V_CHIP_SPARC64X, %g4
|
||||
|
||||
49:
|
||||
mov SUN4V_CHIP_UNKNOWN, %g4
|
||||
|
@ -548,8 +547,7 @@ sun4u_init:
|
|||
stxa %g0, [%g7] ASI_DMMU
|
||||
membar #Sync
|
||||
|
||||
ba,pt %xcc, sun4u_continue
|
||||
nop
|
||||
ba,a,pt %xcc, sun4u_continue
|
||||
|
||||
sun4v_init:
|
||||
/* Set ctx 0 */
|
||||
|
@ -560,14 +558,12 @@ sun4v_init:
|
|||
mov SECONDARY_CONTEXT, %g7
|
||||
stxa %g0, [%g7] ASI_MMU
|
||||
membar #Sync
|
||||
ba,pt %xcc, niagara_tlb_fixup
|
||||
nop
|
||||
ba,a,pt %xcc, niagara_tlb_fixup
|
||||
|
||||
sun4u_continue:
|
||||
BRANCH_IF_ANY_CHEETAH(g1, g7, cheetah_tlb_fixup)
|
||||
|
||||
ba,pt %xcc, spitfire_tlb_fixup
|
||||
nop
|
||||
ba,a,pt %xcc, spitfire_tlb_fixup
|
||||
|
||||
niagara_tlb_fixup:
|
||||
mov 3, %g2 /* Set TLB type to hypervisor. */
|
||||
|
@ -639,8 +635,7 @@ niagara_patch:
|
|||
call hypervisor_patch_cachetlbops
|
||||
nop
|
||||
|
||||
ba,pt %xcc, tlb_fixup_done
|
||||
nop
|
||||
ba,a,pt %xcc, tlb_fixup_done
|
||||
|
||||
cheetah_tlb_fixup:
|
||||
mov 2, %g2 /* Set TLB type to cheetah+. */
|
||||
|
@ -659,8 +654,7 @@ cheetah_tlb_fixup:
|
|||
call cheetah_patch_cachetlbops
|
||||
nop
|
||||
|
||||
ba,pt %xcc, tlb_fixup_done
|
||||
nop
|
||||
ba,a,pt %xcc, tlb_fixup_done
|
||||
|
||||
spitfire_tlb_fixup:
|
||||
/* Set TLB type to spitfire. */
|
||||
|
@ -782,8 +776,7 @@ setup_trap_table:
|
|||
call %o1
|
||||
add %sp, (2047 + 128), %o0
|
||||
|
||||
ba,pt %xcc, 2f
|
||||
nop
|
||||
ba,a,pt %xcc, 2f
|
||||
|
||||
1: sethi %hi(sparc64_ttable_tl0), %o0
|
||||
set prom_set_trap_table_name, %g2
|
||||
|
@ -822,8 +815,7 @@ setup_trap_table:
|
|||
|
||||
BRANCH_IF_ANY_CHEETAH(o2, o3, 1f)
|
||||
|
||||
ba,pt %xcc, 2f
|
||||
nop
|
||||
ba,a,pt %xcc, 2f
|
||||
|
||||
/* Disable STICK_INT interrupts. */
|
||||
1:
|
||||
|
|
|
@ -18,8 +18,7 @@ __do_privact:
|
|||
109: or %g7, %lo(109b), %g7
|
||||
call do_privact
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
.size __do_privact,.-__do_privact
|
||||
|
||||
.type do_mna,#function
|
||||
|
@ -46,8 +45,7 @@ do_mna:
|
|||
mov %l5, %o2
|
||||
call mem_address_unaligned
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
.size do_mna,.-do_mna
|
||||
|
||||
.type do_lddfmna,#function
|
||||
|
@ -65,8 +63,7 @@ do_lddfmna:
|
|||
mov %l5, %o2
|
||||
call handle_lddfmna
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
.size do_lddfmna,.-do_lddfmna
|
||||
|
||||
.type do_stdfmna,#function
|
||||
|
@ -84,8 +81,7 @@ do_stdfmna:
|
|||
mov %l5, %o2
|
||||
call handle_stdfmna
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
.size do_stdfmna,.-do_stdfmna
|
||||
|
||||
.type breakpoint_trap,#function
|
||||
|
|
|
@ -994,6 +994,23 @@ void pcibios_set_master(struct pci_dev *dev)
|
|||
/* No special bus mastering setup handling */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
int pcibios_add_device(struct pci_dev *dev)
|
||||
{
|
||||
struct pci_dev *pdev;
|
||||
|
||||
/* Add sriov arch specific initialization here.
|
||||
* Copy dev_archdata from PF to VF
|
||||
*/
|
||||
if (dev->is_virtfn) {
|
||||
pdev = dev->physfn;
|
||||
memcpy(&dev->dev.archdata, &pdev->dev.archdata,
|
||||
sizeof(struct dev_archdata));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PCI_IOV */
|
||||
|
||||
static int __init pcibios_init(void)
|
||||
{
|
||||
pci_dfl_cache_line_size = 64 >> 2;
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
#include <asm/visasm.h>
|
||||
#include <asm/processor.h>
|
||||
|
||||
#define RTRAP_PSTATE (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
|
||||
#define RTRAP_PSTATE_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
|
||||
#define RTRAP_PSTATE_AG_IRQOFF (PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
|
||||
|
||||
#ifdef CONFIG_CONTEXT_TRACKING
|
||||
# define SCHEDULE_USER schedule_user
|
||||
#else
|
||||
|
@ -236,52 +232,17 @@ rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
|
|||
wrpr %g1, %cwp
|
||||
ba,a,pt %xcc, user_rtt_fill_64bit
|
||||
|
||||
user_rtt_fill_fixup_dax:
|
||||
ba,pt %xcc, user_rtt_fill_fixup_common
|
||||
mov 1, %g3
|
||||
|
||||
user_rtt_fill_fixup_mna:
|
||||
ba,pt %xcc, user_rtt_fill_fixup_common
|
||||
mov 2, %g3
|
||||
|
||||
user_rtt_fill_fixup:
|
||||
rdpr %cwp, %g1
|
||||
add %g1, 1, %g1
|
||||
wrpr %g1, 0x0, %cwp
|
||||
|
||||
rdpr %wstate, %g2
|
||||
sll %g2, 3, %g2
|
||||
wrpr %g2, 0x0, %wstate
|
||||
|
||||
/* We know %canrestore and %otherwin are both zero. */
|
||||
|
||||
sethi %hi(sparc64_kern_pri_context), %g2
|
||||
ldx [%g2 + %lo(sparc64_kern_pri_context)], %g2
|
||||
mov PRIMARY_CONTEXT, %g1
|
||||
|
||||
661: stxa %g2, [%g1] ASI_DMMU
|
||||
.section .sun4v_1insn_patch, "ax"
|
||||
.word 661b
|
||||
stxa %g2, [%g1] ASI_MMU
|
||||
.previous
|
||||
|
||||
sethi %hi(KERNBASE), %g1
|
||||
flush %g1
|
||||
|
||||
or %g4, FAULT_CODE_WINFIXUP, %g4
|
||||
stb %g4, [%g6 + TI_FAULT_CODE]
|
||||
stx %g5, [%g6 + TI_FAULT_ADDR]
|
||||
|
||||
mov %g6, %l1
|
||||
wrpr %g0, 0x0, %tl
|
||||
|
||||
661: nop
|
||||
.section .sun4v_1insn_patch, "ax"
|
||||
.word 661b
|
||||
SET_GL(0)
|
||||
.previous
|
||||
|
||||
wrpr %g0, RTRAP_PSTATE, %pstate
|
||||
|
||||
mov %l1, %g6
|
||||
ldx [%g6 + TI_TASK], %g4
|
||||
LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
|
||||
call do_sparc64_fault
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,pt %xcc, user_rtt_fill_fixup_common
|
||||
clr %g3
|
||||
|
||||
user_rtt_pre_restore:
|
||||
add %g1, 1, %g1
|
||||
|
|
|
@ -138,12 +138,24 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Checks if the fp is valid. We always build signal frames which are
|
||||
* 16-byte aligned, therefore we can always enforce that the restore
|
||||
* frame has that property as well.
|
||||
*/
|
||||
static bool invalid_frame_pointer(void __user *fp, int fplen)
|
||||
{
|
||||
if ((((unsigned long) fp) & 15) ||
|
||||
((unsigned long)fp) > 0x100000000ULL - fplen)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void do_sigreturn32(struct pt_regs *regs)
|
||||
{
|
||||
struct signal_frame32 __user *sf;
|
||||
compat_uptr_t fpu_save;
|
||||
compat_uptr_t rwin_save;
|
||||
unsigned int psr;
|
||||
unsigned int psr, ufp;
|
||||
unsigned pc, npc;
|
||||
sigset_t set;
|
||||
compat_sigset_t seta;
|
||||
|
@ -158,11 +170,16 @@ void do_sigreturn32(struct pt_regs *regs)
|
|||
sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
|
||||
|
||||
/* 1. Make sure we are not getting garbage from the user */
|
||||
if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
|
||||
(((unsigned long) sf) & 3))
|
||||
if (invalid_frame_pointer(sf, sizeof(*sf)))
|
||||
goto segv;
|
||||
|
||||
if (get_user(pc, &sf->info.si_regs.pc) ||
|
||||
if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
|
||||
goto segv;
|
||||
|
||||
if (ufp & 0x7)
|
||||
goto segv;
|
||||
|
||||
if (__get_user(pc, &sf->info.si_regs.pc) ||
|
||||
__get_user(npc, &sf->info.si_regs.npc))
|
||||
goto segv;
|
||||
|
||||
|
@ -227,7 +244,7 @@ segv:
|
|||
asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
|
||||
{
|
||||
struct rt_signal_frame32 __user *sf;
|
||||
unsigned int psr, pc, npc;
|
||||
unsigned int psr, pc, npc, ufp;
|
||||
compat_uptr_t fpu_save;
|
||||
compat_uptr_t rwin_save;
|
||||
sigset_t set;
|
||||
|
@ -242,11 +259,16 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
|
|||
sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
|
||||
|
||||
/* 1. Make sure we are not getting garbage from the user */
|
||||
if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
|
||||
(((unsigned long) sf) & 3))
|
||||
if (invalid_frame_pointer(sf, sizeof(*sf)))
|
||||
goto segv;
|
||||
|
||||
if (get_user(pc, &sf->regs.pc) ||
|
||||
if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
|
||||
goto segv;
|
||||
|
||||
if (ufp & 0x7)
|
||||
goto segv;
|
||||
|
||||
if (__get_user(pc, &sf->regs.pc) ||
|
||||
__get_user(npc, &sf->regs.npc))
|
||||
goto segv;
|
||||
|
||||
|
@ -307,14 +329,6 @@ segv:
|
|||
force_sig(SIGSEGV, current);
|
||||
}
|
||||
|
||||
/* Checks if the fp is valid */
|
||||
static int invalid_frame_pointer(void __user *fp, int fplen)
|
||||
{
|
||||
if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
|
||||
{
|
||||
unsigned long sp;
|
||||
|
|
|
@ -60,10 +60,22 @@ struct rt_signal_frame {
|
|||
#define SF_ALIGNEDSZ (((sizeof(struct signal_frame) + 7) & (~7)))
|
||||
#define RT_ALIGNEDSZ (((sizeof(struct rt_signal_frame) + 7) & (~7)))
|
||||
|
||||
/* Checks if the fp is valid. We always build signal frames which are
|
||||
* 16-byte aligned, therefore we can always enforce that the restore
|
||||
* frame has that property as well.
|
||||
*/
|
||||
static inline bool invalid_frame_pointer(void __user *fp, int fplen)
|
||||
{
|
||||
if ((((unsigned long) fp) & 15) || !__access_ok((unsigned long)fp, fplen))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
asmlinkage void do_sigreturn(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long up_psr, pc, npc, ufp;
|
||||
struct signal_frame __user *sf;
|
||||
unsigned long up_psr, pc, npc;
|
||||
sigset_t set;
|
||||
__siginfo_fpu_t __user *fpu_save;
|
||||
__siginfo_rwin_t __user *rwin_save;
|
||||
|
@ -77,10 +89,13 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
|
|||
sf = (struct signal_frame __user *) regs->u_regs[UREG_FP];
|
||||
|
||||
/* 1. Make sure we are not getting garbage from the user */
|
||||
if (!access_ok(VERIFY_READ, sf, sizeof(*sf)))
|
||||
if (!invalid_frame_pointer(sf, sizeof(*sf)))
|
||||
goto segv_and_exit;
|
||||
|
||||
if (((unsigned long) sf) & 3)
|
||||
if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
|
||||
goto segv_and_exit;
|
||||
|
||||
if (ufp & 0x7)
|
||||
goto segv_and_exit;
|
||||
|
||||
err = __get_user(pc, &sf->info.si_regs.pc);
|
||||
|
@ -127,7 +142,7 @@ segv_and_exit:
|
|||
asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
|
||||
{
|
||||
struct rt_signal_frame __user *sf;
|
||||
unsigned int psr, pc, npc;
|
||||
unsigned int psr, pc, npc, ufp;
|
||||
__siginfo_fpu_t __user *fpu_save;
|
||||
__siginfo_rwin_t __user *rwin_save;
|
||||
sigset_t set;
|
||||
|
@ -135,8 +150,13 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
|
|||
|
||||
synchronize_user_stack();
|
||||
sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
|
||||
if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
|
||||
(((unsigned long) sf) & 0x03))
|
||||
if (!invalid_frame_pointer(sf, sizeof(*sf)))
|
||||
goto segv;
|
||||
|
||||
if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
|
||||
goto segv;
|
||||
|
||||
if (ufp & 0x7)
|
||||
goto segv;
|
||||
|
||||
err = __get_user(pc, &sf->regs.pc);
|
||||
|
@ -178,15 +198,6 @@ segv:
|
|||
force_sig(SIGSEGV, current);
|
||||
}
|
||||
|
||||
/* Checks if the fp is valid */
|
||||
static inline int invalid_frame_pointer(void __user *fp, int fplen)
|
||||
{
|
||||
if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
|
||||
{
|
||||
unsigned long sp = regs->u_regs[UREG_FP];
|
||||
|
|
|
@ -52,7 +52,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
|
|||
unsigned char fenab;
|
||||
int err;
|
||||
|
||||
flush_user_windows();
|
||||
synchronize_user_stack();
|
||||
if (get_thread_wsaved() ||
|
||||
(((unsigned long)ucp) & (sizeof(unsigned long)-1)) ||
|
||||
(!__access_ok(ucp, sizeof(*ucp))))
|
||||
|
@ -234,6 +234,17 @@ do_sigsegv:
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* Checks if the fp is valid. We always build rt signal frames which
|
||||
* are 16-byte aligned, therefore we can always enforce that the
|
||||
* restore frame has that property as well.
|
||||
*/
|
||||
static bool invalid_frame_pointer(void __user *fp)
|
||||
{
|
||||
if (((unsigned long) fp) & 15)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct rt_signal_frame {
|
||||
struct sparc_stackf ss;
|
||||
siginfo_t info;
|
||||
|
@ -246,8 +257,8 @@ struct rt_signal_frame {
|
|||
|
||||
void do_rt_sigreturn(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long tpc, tnpc, tstate, ufp;
|
||||
struct rt_signal_frame __user *sf;
|
||||
unsigned long tpc, tnpc, tstate;
|
||||
__siginfo_fpu_t __user *fpu_save;
|
||||
__siginfo_rwin_t __user *rwin_save;
|
||||
sigset_t set;
|
||||
|
@ -261,10 +272,16 @@ void do_rt_sigreturn(struct pt_regs *regs)
|
|||
(regs->u_regs [UREG_FP] + STACK_BIAS);
|
||||
|
||||
/* 1. Make sure we are not getting garbage from the user */
|
||||
if (((unsigned long) sf) & 3)
|
||||
if (invalid_frame_pointer(sf))
|
||||
goto segv;
|
||||
|
||||
err = get_user(tpc, &sf->regs.tpc);
|
||||
if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
|
||||
goto segv;
|
||||
|
||||
if ((ufp + STACK_BIAS) & 0x7)
|
||||
goto segv;
|
||||
|
||||
err = __get_user(tpc, &sf->regs.tpc);
|
||||
err |= __get_user(tnpc, &sf->regs.tnpc);
|
||||
if (test_thread_flag(TIF_32BIT)) {
|
||||
tpc &= 0xffffffff;
|
||||
|
@ -308,14 +325,6 @@ segv:
|
|||
force_sig(SIGSEGV, current);
|
||||
}
|
||||
|
||||
/* Checks if the fp is valid */
|
||||
static int invalid_frame_pointer(void __user *fp)
|
||||
{
|
||||
if (((unsigned long) fp) & 15)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
|
||||
{
|
||||
unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
|
||||
|
|
|
@ -48,6 +48,10 @@ int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
|||
int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (((unsigned long) fpu) & 3)
|
||||
return -EFAULT;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (test_tsk_thread_flag(current, TIF_USEDFPU))
|
||||
regs->psr &= ~PSR_EF;
|
||||
|
@ -97,7 +101,10 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
|
|||
struct thread_info *t = current_thread_info();
|
||||
int i, wsaved, err;
|
||||
|
||||
__get_user(wsaved, &rp->wsaved);
|
||||
if (((unsigned long) rp) & 3)
|
||||
return -EFAULT;
|
||||
|
||||
get_user(wsaved, &rp->wsaved);
|
||||
if (wsaved > NSWINS)
|
||||
return -EFAULT;
|
||||
|
||||
|
|
|
@ -37,7 +37,10 @@ int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
|
|||
unsigned long fprs;
|
||||
int err;
|
||||
|
||||
err = __get_user(fprs, &fpu->si_fprs);
|
||||
if (((unsigned long) fpu) & 7)
|
||||
return -EFAULT;
|
||||
|
||||
err = get_user(fprs, &fpu->si_fprs);
|
||||
fprs_write(0);
|
||||
regs->tstate &= ~TSTATE_PEF;
|
||||
if (fprs & FPRS_DL)
|
||||
|
@ -72,7 +75,10 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
|
|||
struct thread_info *t = current_thread_info();
|
||||
int i, wsaved, err;
|
||||
|
||||
__get_user(wsaved, &rp->wsaved);
|
||||
if (((unsigned long) rp) & 7)
|
||||
return -EFAULT;
|
||||
|
||||
get_user(wsaved, &rp->wsaved);
|
||||
if (wsaved > NSWINS)
|
||||
return -EFAULT;
|
||||
|
||||
|
|
|
@ -85,8 +85,7 @@ __spitfire_cee_trap_continue:
|
|||
ba,pt %xcc, etraptl1
|
||||
rd %pc, %g7
|
||||
|
||||
ba,pt %xcc, 2f
|
||||
nop
|
||||
ba,a,pt %xcc, 2f
|
||||
|
||||
1: ba,pt %xcc, etrap_irq
|
||||
rd %pc, %g7
|
||||
|
@ -100,8 +99,7 @@ __spitfire_cee_trap_continue:
|
|||
mov %l5, %o2
|
||||
call spitfire_access_error
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
.size __spitfire_access_error,.-__spitfire_access_error
|
||||
|
||||
/* This is the trap handler entry point for ECC correctable
|
||||
|
@ -179,8 +177,7 @@ __spitfire_data_access_exception_tl1:
|
|||
mov %l5, %o2
|
||||
call spitfire_data_access_exception_tl1
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
.size __spitfire_data_access_exception_tl1,.-__spitfire_data_access_exception_tl1
|
||||
|
||||
.type __spitfire_data_access_exception,#function
|
||||
|
@ -200,8 +197,7 @@ __spitfire_data_access_exception:
|
|||
mov %l5, %o2
|
||||
call spitfire_data_access_exception
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
.size __spitfire_data_access_exception,.-__spitfire_data_access_exception
|
||||
|
||||
.type __spitfire_insn_access_exception_tl1,#function
|
||||
|
@ -220,8 +216,7 @@ __spitfire_insn_access_exception_tl1:
|
|||
mov %l5, %o2
|
||||
call spitfire_insn_access_exception_tl1
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
.size __spitfire_insn_access_exception_tl1,.-__spitfire_insn_access_exception_tl1
|
||||
|
||||
.type __spitfire_insn_access_exception,#function
|
||||
|
@ -240,6 +235,5 @@ __spitfire_insn_access_exception:
|
|||
mov %l5, %o2
|
||||
call spitfire_insn_access_exception
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
.size __spitfire_insn_access_exception,.-__spitfire_insn_access_exception
|
||||
|
|
|
@ -158,7 +158,25 @@ linux_syscall_trace32:
|
|||
add %sp, PTREGS_OFF, %o0
|
||||
brnz,pn %o0, 3f
|
||||
mov -ENOSYS, %o0
|
||||
|
||||
/* Syscall tracing can modify the registers. */
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
|
||||
sethi %hi(sys_call_table32), %l7
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0
|
||||
or %l7, %lo(sys_call_table32), %l7
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5
|
||||
|
||||
cmp %g1, NR_syscalls
|
||||
bgeu,pn %xcc, 3f
|
||||
mov -ENOSYS, %o0
|
||||
|
||||
sll %g1, 2, %l4
|
||||
srl %i0, 0, %o0
|
||||
lduw [%l7 + %l4], %l7
|
||||
srl %i4, 0, %o4
|
||||
srl %i1, 0, %o1
|
||||
srl %i2, 0, %o2
|
||||
|
@ -170,7 +188,25 @@ linux_syscall_trace:
|
|||
add %sp, PTREGS_OFF, %o0
|
||||
brnz,pn %o0, 3f
|
||||
mov -ENOSYS, %o0
|
||||
|
||||
/* Syscall tracing can modify the registers. */
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
|
||||
sethi %hi(sys_call_table64), %l7
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0
|
||||
or %l7, %lo(sys_call_table64), %l7
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4
|
||||
ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5
|
||||
|
||||
cmp %g1, NR_syscalls
|
||||
bgeu,pn %xcc, 3f
|
||||
mov -ENOSYS, %o0
|
||||
|
||||
sll %g1, 2, %l4
|
||||
mov %i0, %o0
|
||||
lduw [%l7 + %l4], %l7
|
||||
mov %i1, %o1
|
||||
mov %i2, %o2
|
||||
mov %i3, %o3
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
#include <asm/thread_info.h>
|
||||
#include <asm/trap_block.h>
|
||||
#include <asm/spitfire.h>
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/head.h>
|
||||
|
||||
.text
|
||||
.align 8
|
||||
.globl user_rtt_fill_fixup_common
|
||||
user_rtt_fill_fixup_common:
|
||||
rdpr %cwp, %g1
|
||||
add %g1, 1, %g1
|
||||
wrpr %g1, 0x0, %cwp
|
||||
|
||||
rdpr %wstate, %g2
|
||||
sll %g2, 3, %g2
|
||||
wrpr %g2, 0x0, %wstate
|
||||
|
||||
/* We know %canrestore and %otherwin are both zero. */
|
||||
|
||||
sethi %hi(sparc64_kern_pri_context), %g2
|
||||
ldx [%g2 + %lo(sparc64_kern_pri_context)], %g2
|
||||
mov PRIMARY_CONTEXT, %g1
|
||||
|
||||
661: stxa %g2, [%g1] ASI_DMMU
|
||||
.section .sun4v_1insn_patch, "ax"
|
||||
.word 661b
|
||||
stxa %g2, [%g1] ASI_MMU
|
||||
.previous
|
||||
|
||||
sethi %hi(KERNBASE), %g1
|
||||
flush %g1
|
||||
|
||||
mov %g4, %l4
|
||||
mov %g5, %l5
|
||||
brnz,pn %g3, 1f
|
||||
mov %g3, %l3
|
||||
|
||||
or %g4, FAULT_CODE_WINFIXUP, %g4
|
||||
stb %g4, [%g6 + TI_FAULT_CODE]
|
||||
stx %g5, [%g6 + TI_FAULT_ADDR]
|
||||
1:
|
||||
mov %g6, %l1
|
||||
wrpr %g0, 0x0, %tl
|
||||
|
||||
661: nop
|
||||
.section .sun4v_1insn_patch, "ax"
|
||||
.word 661b
|
||||
SET_GL(0)
|
||||
.previous
|
||||
|
||||
wrpr %g0, RTRAP_PSTATE, %pstate
|
||||
|
||||
mov %l1, %g6
|
||||
ldx [%g6 + TI_TASK], %g4
|
||||
LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
|
||||
|
||||
brnz,pn %l3, 1f
|
||||
nop
|
||||
|
||||
call do_sparc64_fault
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
|
||||
1: cmp %g3, 2
|
||||
bne,pn %xcc, 2f
|
||||
nop
|
||||
|
||||
sethi %hi(tlb_type), %g1
|
||||
lduw [%g1 + %lo(tlb_type)], %g1
|
||||
cmp %g1, 3
|
||||
bne,pt %icc, 1f
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
mov %l4, %o2
|
||||
call sun4v_do_mna
|
||||
mov %l5, %o1
|
||||
ba,a,pt %xcc, rtrap
|
||||
1: mov %l4, %o1
|
||||
mov %l5, %o2
|
||||
call mem_address_unaligned
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
|
||||
2: sethi %hi(tlb_type), %g1
|
||||
mov %l4, %o1
|
||||
lduw [%g1 + %lo(tlb_type)], %g1
|
||||
mov %l5, %o2
|
||||
cmp %g1, 3
|
||||
bne,pt %icc, 1f
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
call sun4v_data_access_exception
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
|
||||
1: call spitfire_data_access_exception
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
|
@ -11,8 +11,7 @@ utrap_trap: /* %g3=handler,%g4=level */
|
|||
mov %l4, %o1
|
||||
call bad_trap
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
|
||||
invoke_utrap:
|
||||
sllx %g3, 3, %g3
|
||||
|
|
|
@ -33,6 +33,10 @@ ENTRY(_start)
|
|||
jiffies = jiffies_64;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPARC64
|
||||
ASSERT((swapper_tsb == 0x0000000000408000), "Error: sparc64 early assembler too large")
|
||||
#endif
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
#ifdef CONFIG_SPARC64
|
||||
|
|
|
@ -32,8 +32,7 @@ fill_fixup:
|
|||
rd %pc, %g7
|
||||
call do_sparc64_fault
|
||||
add %sp, PTREGS_OFF, %o0
|
||||
ba,pt %xcc, rtrap
|
||||
nop
|
||||
ba,a,pt %xcc, rtrap
|
||||
|
||||
/* Be very careful about usage of the trap globals here.
|
||||
* You cannot touch %g5 as that has the fault information.
|
||||
|
|
|
@ -1301,10 +1301,18 @@ static int __init numa_parse_sun4u(void)
|
|||
|
||||
static int __init bootmem_init_numa(void)
|
||||
{
|
||||
int i, j;
|
||||
int err = -1;
|
||||
|
||||
numadbg("bootmem_init_numa()\n");
|
||||
|
||||
/* Some sane defaults for numa latency values */
|
||||
for (i = 0; i < MAX_NUMNODES; i++) {
|
||||
for (j = 0; j < MAX_NUMNODES; j++)
|
||||
numa_latency[i][j] = (i == j) ?
|
||||
LOCAL_DISTANCE : REMOTE_DISTANCE;
|
||||
}
|
||||
|
||||
if (numa_enabled) {
|
||||
if (tlb_type == hypervisor)
|
||||
err = numa_parse_mdesc();
|
||||
|
@ -2762,9 +2770,10 @@ void hugetlb_setup(struct pt_regs *regs)
|
|||
* the Data-TLB for huge pages.
|
||||
*/
|
||||
if (tlb_type == cheetah_plus) {
|
||||
bool need_context_reload = false;
|
||||
unsigned long ctx;
|
||||
|
||||
spin_lock(&ctx_alloc_lock);
|
||||
spin_lock_irq(&ctx_alloc_lock);
|
||||
ctx = mm->context.sparc64_ctx_val;
|
||||
ctx &= ~CTX_PGSZ_MASK;
|
||||
ctx |= CTX_PGSZ_BASE << CTX_PGSZ0_SHIFT;
|
||||
|
@ -2783,9 +2792,12 @@ void hugetlb_setup(struct pt_regs *regs)
|
|||
* also executing in this address space.
|
||||
*/
|
||||
mm->context.sparc64_ctx_val = ctx;
|
||||
on_each_cpu(context_reload, mm, 0);
|
||||
need_context_reload = true;
|
||||
}
|
||||
spin_unlock(&ctx_alloc_lock);
|
||||
spin_unlock_irq(&ctx_alloc_lock);
|
||||
|
||||
if (need_context_reload)
|
||||
on_each_cpu(context_reload, mm, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -162,6 +162,9 @@ isoimage: $(obj)/bzImage
|
|||
for i in lib lib64 share end ; do \
|
||||
if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
|
||||
cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
|
||||
if [ -f /usr/$$i/syslinux/ldlinux.c32 ]; then \
|
||||
cp /usr/$$i/syslinux/ldlinux.c32 $(obj)/isoimage ; \
|
||||
fi ; \
|
||||
break ; \
|
||||
fi ; \
|
||||
if [ $$i = end ] ; then exit 1 ; fi ; \
|
||||
|
|
|
@ -385,6 +385,9 @@ static void intel_thermal_interrupt(void)
|
|||
{
|
||||
__u64 msr_val;
|
||||
|
||||
if (static_cpu_has(X86_FEATURE_HWP))
|
||||
wrmsrl_safe(MSR_HWP_STATUS, 0);
|
||||
|
||||
rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
|
||||
|
||||
/* Check for violation of core thermal thresholds*/
|
||||
|
|
|
@ -959,7 +959,19 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
|||
* normal page fault.
|
||||
*/
|
||||
regs->ip = (unsigned long)cur->addr;
|
||||
/*
|
||||
* Trap flag (TF) has been set here because this fault
|
||||
* happened where the single stepping will be done.
|
||||
* So clear it by resetting the current kprobe:
|
||||
*/
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
|
||||
/*
|
||||
* If the TF flag was set before the kprobe hit,
|
||||
* don't touch it:
|
||||
*/
|
||||
regs->flags |= kcb->kprobe_old_flags;
|
||||
|
||||
if (kcb->kprobe_status == KPROBE_REENTER)
|
||||
restore_previous_kprobe(kcb);
|
||||
else
|
||||
|
|
|
@ -501,6 +501,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
|
|||
do_cpuid_1_ent(&entry[i], function, idx);
|
||||
if (idx == 1) {
|
||||
entry[i].eax &= kvm_supported_word10_x86_features;
|
||||
cpuid_mask(&entry[i].eax, 10);
|
||||
entry[i].ebx = 0;
|
||||
if (entry[i].eax & (F(XSAVES)|F(XSAVEC)))
|
||||
entry[i].ebx =
|
||||
|
|
|
@ -3174,6 +3174,11 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
|
|||
if (dbgregs->flags)
|
||||
return -EINVAL;
|
||||
|
||||
if (dbgregs->dr6 & ~0xffffffffull)
|
||||
return -EINVAL;
|
||||
if (dbgregs->dr7 & ~0xffffffffull)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
|
||||
kvm_update_dr0123(vcpu);
|
||||
vcpu->arch.dr6 = dbgregs->dr6;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
struct kmmio_fault_page {
|
||||
struct list_head list;
|
||||
struct kmmio_fault_page *release_next;
|
||||
unsigned long page; /* location of the fault page */
|
||||
unsigned long addr; /* the requested address */
|
||||
pteval_t old_presence; /* page presence prior to arming */
|
||||
bool armed;
|
||||
|
||||
|
@ -70,9 +70,16 @@ unsigned int kmmio_count;
|
|||
static struct list_head kmmio_page_table[KMMIO_PAGE_TABLE_SIZE];
|
||||
static LIST_HEAD(kmmio_probes);
|
||||
|
||||
static struct list_head *kmmio_page_list(unsigned long page)
|
||||
static struct list_head *kmmio_page_list(unsigned long addr)
|
||||
{
|
||||
return &kmmio_page_table[hash_long(page, KMMIO_PAGE_HASH_BITS)];
|
||||
unsigned int l;
|
||||
pte_t *pte = lookup_address(addr, &l);
|
||||
|
||||
if (!pte)
|
||||
return NULL;
|
||||
addr &= page_level_mask(l);
|
||||
|
||||
return &kmmio_page_table[hash_long(addr, KMMIO_PAGE_HASH_BITS)];
|
||||
}
|
||||
|
||||
/* Accessed per-cpu */
|
||||
|
@ -98,15 +105,19 @@ static struct kmmio_probe *get_kmmio_probe(unsigned long addr)
|
|||
}
|
||||
|
||||
/* You must be holding RCU read lock. */
|
||||
static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long page)
|
||||
static struct kmmio_fault_page *get_kmmio_fault_page(unsigned long addr)
|
||||
{
|
||||
struct list_head *head;
|
||||
struct kmmio_fault_page *f;
|
||||
unsigned int l;
|
||||
pte_t *pte = lookup_address(addr, &l);
|
||||
|
||||
page &= PAGE_MASK;
|
||||
head = kmmio_page_list(page);
|
||||
if (!pte)
|
||||
return NULL;
|
||||
addr &= page_level_mask(l);
|
||||
head = kmmio_page_list(addr);
|
||||
list_for_each_entry_rcu(f, head, list) {
|
||||
if (f->page == page)
|
||||
if (f->addr == addr)
|
||||
return f;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -137,10 +148,10 @@ static void clear_pte_presence(pte_t *pte, bool clear, pteval_t *old)
|
|||
static int clear_page_presence(struct kmmio_fault_page *f, bool clear)
|
||||
{
|
||||
unsigned int level;
|
||||
pte_t *pte = lookup_address(f->page, &level);
|
||||
pte_t *pte = lookup_address(f->addr, &level);
|
||||
|
||||
if (!pte) {
|
||||
pr_err("no pte for page 0x%08lx\n", f->page);
|
||||
pr_err("no pte for addr 0x%08lx\n", f->addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -156,7 +167,7 @@ static int clear_page_presence(struct kmmio_fault_page *f, bool clear)
|
|||
return -1;
|
||||
}
|
||||
|
||||
__flush_tlb_one(f->page);
|
||||
__flush_tlb_one(f->addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -176,12 +187,12 @@ static int arm_kmmio_fault_page(struct kmmio_fault_page *f)
|
|||
int ret;
|
||||
WARN_ONCE(f->armed, KERN_ERR pr_fmt("kmmio page already armed.\n"));
|
||||
if (f->armed) {
|
||||
pr_warning("double-arm: page 0x%08lx, ref %d, old %d\n",
|
||||
f->page, f->count, !!f->old_presence);
|
||||
pr_warning("double-arm: addr 0x%08lx, ref %d, old %d\n",
|
||||
f->addr, f->count, !!f->old_presence);
|
||||
}
|
||||
ret = clear_page_presence(f, true);
|
||||
WARN_ONCE(ret < 0, KERN_ERR pr_fmt("arming 0x%08lx failed.\n"),
|
||||
f->page);
|
||||
WARN_ONCE(ret < 0, KERN_ERR pr_fmt("arming at 0x%08lx failed.\n"),
|
||||
f->addr);
|
||||
f->armed = true;
|
||||
return ret;
|
||||
}
|
||||
|
@ -191,7 +202,7 @@ static void disarm_kmmio_fault_page(struct kmmio_fault_page *f)
|
|||
{
|
||||
int ret = clear_page_presence(f, false);
|
||||
WARN_ONCE(ret < 0,
|
||||
KERN_ERR "kmmio disarming 0x%08lx failed.\n", f->page);
|
||||
KERN_ERR "kmmio disarming at 0x%08lx failed.\n", f->addr);
|
||||
f->armed = false;
|
||||
}
|
||||
|
||||
|
@ -215,6 +226,12 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
|
|||
struct kmmio_context *ctx;
|
||||
struct kmmio_fault_page *faultpage;
|
||||
int ret = 0; /* default to fault not handled */
|
||||
unsigned long page_base = addr;
|
||||
unsigned int l;
|
||||
pte_t *pte = lookup_address(addr, &l);
|
||||
if (!pte)
|
||||
return -EINVAL;
|
||||
page_base &= page_level_mask(l);
|
||||
|
||||
/*
|
||||
* Preemption is now disabled to prevent process switch during
|
||||
|
@ -227,7 +244,7 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
|
|||
preempt_disable();
|
||||
rcu_read_lock();
|
||||
|
||||
faultpage = get_kmmio_fault_page(addr);
|
||||
faultpage = get_kmmio_fault_page(page_base);
|
||||
if (!faultpage) {
|
||||
/*
|
||||
* Either this page fault is not caused by kmmio, or
|
||||
|
@ -239,7 +256,7 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
|
|||
|
||||
ctx = &get_cpu_var(kmmio_ctx);
|
||||
if (ctx->active) {
|
||||
if (addr == ctx->addr) {
|
||||
if (page_base == ctx->addr) {
|
||||
/*
|
||||
* A second fault on the same page means some other
|
||||
* condition needs handling by do_page_fault(), the
|
||||
|
@ -267,9 +284,9 @@ int kmmio_handler(struct pt_regs *regs, unsigned long addr)
|
|||
ctx->active++;
|
||||
|
||||
ctx->fpage = faultpage;
|
||||
ctx->probe = get_kmmio_probe(addr);
|
||||
ctx->probe = get_kmmio_probe(page_base);
|
||||
ctx->saved_flags = (regs->flags & (X86_EFLAGS_TF | X86_EFLAGS_IF));
|
||||
ctx->addr = addr;
|
||||
ctx->addr = page_base;
|
||||
|
||||
if (ctx->probe && ctx->probe->pre_handler)
|
||||
ctx->probe->pre_handler(ctx->probe, regs, addr);
|
||||
|
@ -354,12 +371,11 @@ out:
|
|||
}
|
||||
|
||||
/* You must be holding kmmio_lock. */
|
||||
static int add_kmmio_fault_page(unsigned long page)
|
||||
static int add_kmmio_fault_page(unsigned long addr)
|
||||
{
|
||||
struct kmmio_fault_page *f;
|
||||
|
||||
page &= PAGE_MASK;
|
||||
f = get_kmmio_fault_page(page);
|
||||
f = get_kmmio_fault_page(addr);
|
||||
if (f) {
|
||||
if (!f->count)
|
||||
arm_kmmio_fault_page(f);
|
||||
|
@ -372,26 +388,25 @@ static int add_kmmio_fault_page(unsigned long page)
|
|||
return -1;
|
||||
|
||||
f->count = 1;
|
||||
f->page = page;
|
||||
f->addr = addr;
|
||||
|
||||
if (arm_kmmio_fault_page(f)) {
|
||||
kfree(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
list_add_rcu(&f->list, kmmio_page_list(f->page));
|
||||
list_add_rcu(&f->list, kmmio_page_list(f->addr));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* You must be holding kmmio_lock. */
|
||||
static void release_kmmio_fault_page(unsigned long page,
|
||||
static void release_kmmio_fault_page(unsigned long addr,
|
||||
struct kmmio_fault_page **release_list)
|
||||
{
|
||||
struct kmmio_fault_page *f;
|
||||
|
||||
page &= PAGE_MASK;
|
||||
f = get_kmmio_fault_page(page);
|
||||
f = get_kmmio_fault_page(addr);
|
||||
if (!f)
|
||||
return;
|
||||
|
||||
|
@ -420,18 +435,27 @@ int register_kmmio_probe(struct kmmio_probe *p)
|
|||
int ret = 0;
|
||||
unsigned long size = 0;
|
||||
const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK);
|
||||
unsigned int l;
|
||||
pte_t *pte;
|
||||
|
||||
spin_lock_irqsave(&kmmio_lock, flags);
|
||||
if (get_kmmio_probe(p->addr)) {
|
||||
ret = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pte = lookup_address(p->addr, &l);
|
||||
if (!pte) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
kmmio_count++;
|
||||
list_add_rcu(&p->list, &kmmio_probes);
|
||||
while (size < size_lim) {
|
||||
if (add_kmmio_fault_page(p->addr + size))
|
||||
pr_err("Unable to set page fault.\n");
|
||||
size += PAGE_SIZE;
|
||||
size += page_level_size(l);
|
||||
}
|
||||
out:
|
||||
spin_unlock_irqrestore(&kmmio_lock, flags);
|
||||
|
@ -506,11 +530,17 @@ void unregister_kmmio_probe(struct kmmio_probe *p)
|
|||
const unsigned long size_lim = p->len + (p->addr & ~PAGE_MASK);
|
||||
struct kmmio_fault_page *release_list = NULL;
|
||||
struct kmmio_delayed_release *drelease;
|
||||
unsigned int l;
|
||||
pte_t *pte;
|
||||
|
||||
pte = lookup_address(p->addr, &l);
|
||||
if (!pte)
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(&kmmio_lock, flags);
|
||||
while (size < size_lim) {
|
||||
release_kmmio_fault_page(p->addr + size, &release_list);
|
||||
size += PAGE_SIZE;
|
||||
size += page_level_size(l);
|
||||
}
|
||||
list_del_rcu(&p->list);
|
||||
kmmio_count--;
|
||||
|
|
|
@ -14,6 +14,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
|
|||
select MPILIB
|
||||
select PUBLIC_KEY_ALGO_RSA
|
||||
select CRYPTO_HASH_INFO
|
||||
select CRYPTO_AKCIPHER
|
||||
help
|
||||
This option provides support for asymmetric public key type handling.
|
||||
If signature generation and/or verification are to be used,
|
||||
|
|
|
@ -174,6 +174,8 @@ int pkcs7_validate_trust(struct pkcs7_message *pkcs7,
|
|||
int cached_ret = -ENOKEY;
|
||||
int ret;
|
||||
|
||||
*_trusted = false;
|
||||
|
||||
for (p = pkcs7->certs; p; p = p->next)
|
||||
p->seen = false;
|
||||
|
||||
|
|
|
@ -475,6 +475,58 @@ static void acpi_processor_remove(struct acpi_device *device)
|
|||
}
|
||||
#endif /* CONFIG_ACPI_HOTPLUG_CPU */
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
static bool acpi_hwp_native_thermal_lvt_set;
|
||||
static acpi_status __init acpi_hwp_native_thermal_lvt_osc(acpi_handle handle,
|
||||
u32 lvl,
|
||||
void *context,
|
||||
void **rv)
|
||||
{
|
||||
u8 sb_uuid_str[] = "4077A616-290C-47BE-9EBD-D87058713953";
|
||||
u32 capbuf[2];
|
||||
struct acpi_osc_context osc_context = {
|
||||
.uuid_str = sb_uuid_str,
|
||||
.rev = 1,
|
||||
.cap.length = 8,
|
||||
.cap.pointer = capbuf,
|
||||
};
|
||||
|
||||
if (acpi_hwp_native_thermal_lvt_set)
|
||||
return AE_CTRL_TERMINATE;
|
||||
|
||||
capbuf[0] = 0x0000;
|
||||
capbuf[1] = 0x1000; /* set bit 12 */
|
||||
|
||||
if (ACPI_SUCCESS(acpi_run_osc(handle, &osc_context))) {
|
||||
if (osc_context.ret.pointer && osc_context.ret.length > 1) {
|
||||
u32 *capbuf_ret = osc_context.ret.pointer;
|
||||
|
||||
if (capbuf_ret[1] & 0x1000) {
|
||||
acpi_handle_info(handle,
|
||||
"_OSC native thermal LVT Acked\n");
|
||||
acpi_hwp_native_thermal_lvt_set = true;
|
||||
}
|
||||
}
|
||||
kfree(osc_context.ret.pointer);
|
||||
}
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
void __init acpi_early_processor_osc(void)
|
||||
{
|
||||
if (boot_cpu_has(X86_FEATURE_HWP)) {
|
||||
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
|
||||
ACPI_UINT32_MAX,
|
||||
acpi_hwp_native_thermal_lvt_osc,
|
||||
NULL, NULL, NULL);
|
||||
acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID,
|
||||
acpi_hwp_native_thermal_lvt_osc,
|
||||
NULL, NULL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The following ACPI IDs are known to be suitable for representing as
|
||||
* processor devices.
|
||||
|
|
|
@ -612,6 +612,9 @@ static int __init acpi_bus_init(void)
|
|||
goto error1;
|
||||
}
|
||||
|
||||
/* Set capability bits for _OSC under processor scope */
|
||||
acpi_early_processor_osc();
|
||||
|
||||
/*
|
||||
* _OSC method may exist in module level code,
|
||||
* so it must be run after ACPI_FULL_INITIALIZATION
|
||||
|
|
|
@ -121,6 +121,12 @@ void acpi_early_processor_set_pdc(void);
|
|||
static inline void acpi_early_processor_set_pdc(void) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86
|
||||
void acpi_early_processor_osc(void);
|
||||
#else
|
||||
static inline void acpi_early_processor_osc(void) {}
|
||||
#endif
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Embedded Controller
|
||||
-------------------------------------------------------------------------- */
|
||||
|
|
|
@ -606,7 +606,7 @@ void ata_scsi_error(struct Scsi_Host *host)
|
|||
ata_scsi_port_error_handler(host, ap);
|
||||
|
||||
/* finish or retry handled scmd's and clean up */
|
||||
WARN_ON(host->host_failed || !list_empty(&eh_work_q));
|
||||
WARN_ON(!list_empty(&eh_work_q));
|
||||
|
||||
DPRINTK("EXIT\n");
|
||||
}
|
||||
|
|
|
@ -24,10 +24,12 @@ static char *make_driver_name(struct device_driver *drv)
|
|||
|
||||
static void module_create_drivers_dir(struct module_kobject *mk)
|
||||
{
|
||||
if (!mk || mk->drivers_dir)
|
||||
return;
|
||||
static DEFINE_MUTEX(drivers_dir_mutex);
|
||||
|
||||
mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
|
||||
mutex_lock(&drivers_dir_mutex);
|
||||
if (mk && !mk->drivers_dir)
|
||||
mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
|
||||
mutex_unlock(&drivers_dir_mutex);
|
||||
}
|
||||
|
||||
void module_add_driver(struct module *mod, struct device_driver *drv)
|
||||
|
|
|
@ -2946,9 +2946,15 @@ static int mtip_service_thread(void *data)
|
|||
* is in progress nor error handling is active
|
||||
*/
|
||||
wait_event_interruptible(port->svc_wait, (port->flags) &&
|
||||
!(port->flags & MTIP_PF_PAUSE_IO));
|
||||
(port->flags & MTIP_PF_SVC_THD_WORK));
|
||||
|
||||
set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags);
|
||||
if (kthread_should_stop() ||
|
||||
test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags))
|
||||
goto st_out;
|
||||
|
||||
if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT,
|
||||
&dd->dd_flag)))
|
||||
goto st_out;
|
||||
|
||||
if (kthread_should_stop() ||
|
||||
test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags))
|
||||
|
@ -2962,6 +2968,8 @@ static int mtip_service_thread(void *data)
|
|||
&dd->dd_flag)))
|
||||
goto st_out;
|
||||
|
||||
set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags);
|
||||
|
||||
restart_eh:
|
||||
/* Demux bits: start with error handling */
|
||||
if (test_bit(MTIP_PF_EH_ACTIVE_BIT, &port->flags)) {
|
||||
|
@ -3004,10 +3012,8 @@ restart_eh:
|
|||
}
|
||||
|
||||
if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) {
|
||||
if (mtip_ftl_rebuild_poll(dd) < 0)
|
||||
set_bit(MTIP_DDF_REBUILD_FAILED_BIT,
|
||||
&dd->dd_flag);
|
||||
clear_bit(MTIP_PF_REBUILD_BIT, &port->flags);
|
||||
if (mtip_ftl_rebuild_poll(dd) == 0)
|
||||
clear_bit(MTIP_PF_REBUILD_BIT, &port->flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3887,7 +3893,6 @@ static int mtip_block_initialize(struct driver_data *dd)
|
|||
|
||||
mtip_hw_debugfs_init(dd);
|
||||
|
||||
skip_create_disk:
|
||||
memset(&dd->tags, 0, sizeof(dd->tags));
|
||||
dd->tags.ops = &mtip_mq_ops;
|
||||
dd->tags.nr_hw_queues = 1;
|
||||
|
@ -3917,6 +3922,7 @@ skip_create_disk:
|
|||
dd->disk->queue = dd->queue;
|
||||
dd->queue->queuedata = dd;
|
||||
|
||||
skip_create_disk:
|
||||
/* Initialize the protocol layer. */
|
||||
wait_for_rebuild = mtip_hw_get_identify(dd);
|
||||
if (wait_for_rebuild < 0) {
|
||||
|
@ -4078,7 +4084,8 @@ static int mtip_block_remove(struct driver_data *dd)
|
|||
dd->bdev = NULL;
|
||||
}
|
||||
if (dd->disk) {
|
||||
del_gendisk(dd->disk);
|
||||
if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag))
|
||||
del_gendisk(dd->disk);
|
||||
if (dd->disk->queue) {
|
||||
blk_cleanup_queue(dd->queue);
|
||||
blk_mq_free_tag_set(&dd->tags);
|
||||
|
@ -4119,7 +4126,8 @@ static int mtip_block_shutdown(struct driver_data *dd)
|
|||
dev_info(&dd->pdev->dev,
|
||||
"Shutting down %s ...\n", dd->disk->disk_name);
|
||||
|
||||
del_gendisk(dd->disk);
|
||||
if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag))
|
||||
del_gendisk(dd->disk);
|
||||
if (dd->disk->queue) {
|
||||
blk_cleanup_queue(dd->queue);
|
||||
blk_mq_free_tag_set(&dd->tags);
|
||||
|
|
|
@ -145,6 +145,11 @@ enum {
|
|||
MTIP_PF_SR_CLEANUP_BIT = 7,
|
||||
MTIP_PF_SVC_THD_STOP_BIT = 8,
|
||||
|
||||
MTIP_PF_SVC_THD_WORK = ((1 << MTIP_PF_EH_ACTIVE_BIT) |
|
||||
(1 << MTIP_PF_ISSUE_CMDS_BIT) |
|
||||
(1 << MTIP_PF_REBUILD_BIT) |
|
||||
(1 << MTIP_PF_SVC_THD_STOP_BIT)),
|
||||
|
||||
/* below are bit numbers in 'dd_flag' defined in driver_data */
|
||||
MTIP_DDF_SEC_LOCK_BIT = 0,
|
||||
MTIP_DDF_REMOVE_PENDING_BIT = 1,
|
||||
|
|
|
@ -557,8 +557,8 @@ static void do_nbd_request(struct request_queue *q)
|
|||
req, req->cmd_type);
|
||||
|
||||
if (unlikely(!nbd->sock)) {
|
||||
dev_err(disk_to_dev(nbd->disk),
|
||||
"Attempted send on closed socket\n");
|
||||
dev_err_ratelimited(disk_to_dev(nbd->disk),
|
||||
"Attempted send on closed socket\n");
|
||||
req->errors++;
|
||||
nbd_end_request(nbd, req);
|
||||
spin_lock_irq(q->queue_lock);
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
*/
|
||||
#include <linux/types.h>
|
||||
|
||||
static bool verbose = 0;
|
||||
static int verbose = 0;
|
||||
static int major = PD_MAJOR;
|
||||
static char *name = PD_NAME;
|
||||
static int cluster = 64;
|
||||
|
@ -161,7 +161,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_GEO, D_SBY, D_DLY, D_SLV};
|
|||
static DEFINE_MUTEX(pd_mutex);
|
||||
static DEFINE_SPINLOCK(pd_lock);
|
||||
|
||||
module_param(verbose, bool, 0);
|
||||
module_param(verbose, int, 0);
|
||||
module_param(major, int, 0);
|
||||
module_param(name, charp, 0);
|
||||
module_param(cluster, int, 0);
|
||||
|
|
|
@ -117,7 +117,7 @@
|
|||
|
||||
*/
|
||||
|
||||
static bool verbose = 0;
|
||||
static int verbose = 0;
|
||||
static int major = PT_MAJOR;
|
||||
static char *name = PT_NAME;
|
||||
static int disable = 0;
|
||||
|
@ -152,7 +152,7 @@ static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
|
|||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
module_param(verbose, bool, 0);
|
||||
module_param(verbose, int, 0);
|
||||
module_param(major, int, 0);
|
||||
module_param(name, charp, 0);
|
||||
module_param_array(drive0, int, NULL, 0);
|
||||
|
|
|
@ -3813,6 +3813,7 @@ static void handle_new_recv_msgs(ipmi_smi_t intf)
|
|||
while (!list_empty(&intf->waiting_rcv_msgs)) {
|
||||
smi_msg = list_entry(intf->waiting_rcv_msgs.next,
|
||||
struct ipmi_smi_msg, link);
|
||||
list_del(&smi_msg->link);
|
||||
if (!run_to_completion)
|
||||
spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock,
|
||||
flags);
|
||||
|
@ -3822,11 +3823,14 @@ static void handle_new_recv_msgs(ipmi_smi_t intf)
|
|||
if (rv > 0) {
|
||||
/*
|
||||
* To preserve message order, quit if we
|
||||
* can't handle a message.
|
||||
* can't handle a message. Add the message
|
||||
* back at the head, this is safe because this
|
||||
* tasklet is the only thing that pulls the
|
||||
* messages.
|
||||
*/
|
||||
list_add(&smi_msg->link, &intf->waiting_rcv_msgs);
|
||||
break;
|
||||
} else {
|
||||
list_del(&smi_msg->link);
|
||||
if (rv == 0)
|
||||
/* Message handled */
|
||||
ipmi_free_smi_msg(smi_msg);
|
||||
|
|
|
@ -133,6 +133,8 @@ struct tpm_chip *tpmm_chip_alloc(struct device *dev,
|
|||
chip->cdev.owner = chip->pdev->driver->owner;
|
||||
chip->cdev.kobj.parent = &chip->dev.kobj;
|
||||
|
||||
devm_add_action(dev, (void (*)(void *)) put_device, &chip->dev);
|
||||
|
||||
return chip;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(tpmm_chip_alloc);
|
||||
|
@ -168,7 +170,7 @@ static int tpm_dev_add_device(struct tpm_chip *chip)
|
|||
static void tpm_dev_del_device(struct tpm_chip *chip)
|
||||
{
|
||||
cdev_del(&chip->cdev);
|
||||
device_unregister(&chip->dev);
|
||||
device_del(&chip->dev);
|
||||
}
|
||||
|
||||
static int tpm1_chip_register(struct tpm_chip *chip)
|
||||
|
|
|
@ -1961,6 +1961,7 @@ static struct clk_branch gcc_crypto_ahb_clk = {
|
|||
"pcnoc_bfdcd_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
|
@ -1996,6 +1997,7 @@ static struct clk_branch gcc_crypto_clk = {
|
|||
"crypto_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -2753,7 +2753,7 @@ static struct clk_rcg ce3_src = {
|
|||
},
|
||||
.freq_tbl = clk_tbl_ce3,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2c08,
|
||||
.enable_reg = 0x36c0,
|
||||
.enable_mask = BIT(7),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ce3_src",
|
||||
|
@ -2769,7 +2769,7 @@ static struct clk_branch ce3_core_clk = {
|
|||
.halt_reg = 0x2fdc,
|
||||
.halt_bit = 5,
|
||||
.clkr = {
|
||||
.enable_reg = 0x36c4,
|
||||
.enable_reg = 0x36cc,
|
||||
.enable_mask = BIT(4),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ce3_core_clk",
|
||||
|
|
|
@ -131,6 +131,7 @@ struct clk *rockchip_clk_register_mmc(const char *name,
|
|||
if (!mmc_clock)
|
||||
return NULL;
|
||||
|
||||
init.flags = 0;
|
||||
init.num_parents = num_parents;
|
||||
init.parent_names = parent_names;
|
||||
init.ops = &rockchip_mmc_clk_ops;
|
||||
|
|
|
@ -70,7 +70,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
|
|||
if (gate_offset >= 0) {
|
||||
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
|
||||
if (!gate)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
goto err_gate;
|
||||
|
||||
gate->flags = gate_flags;
|
||||
gate->reg = base + gate_offset;
|
||||
|
@ -82,7 +82,7 @@ static struct clk *rockchip_clk_register_branch(const char *name,
|
|||
if (div_width > 0) {
|
||||
div = kzalloc(sizeof(*div), GFP_KERNEL);
|
||||
if (!div)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
goto err_div;
|
||||
|
||||
div->flags = div_flags;
|
||||
div->reg = base + muxdiv_offset;
|
||||
|
@ -100,6 +100,11 @@ static struct clk *rockchip_clk_register_branch(const char *name,
|
|||
flags);
|
||||
|
||||
return clk;
|
||||
err_div:
|
||||
kfree(gate);
|
||||
err_gate:
|
||||
kfree(mux);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
static struct clk *rockchip_clk_register_frac_branch(const char *name,
|
||||
|
|
|
@ -141,6 +141,7 @@ void __init clk_sp810_of_setup(struct device_node *node)
|
|||
const char *parent_names[2];
|
||||
char name[12];
|
||||
struct clk_init_data init;
|
||||
static int instance;
|
||||
int i;
|
||||
|
||||
if (!sp810) {
|
||||
|
@ -172,7 +173,7 @@ void __init clk_sp810_of_setup(struct device_node *node)
|
|||
init.num_parents = ARRAY_SIZE(parent_names);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sp810->timerclken); i++) {
|
||||
snprintf(name, ARRAY_SIZE(name), "timerclken%d", i);
|
||||
snprintf(name, sizeof(name), "sp810_%d_%d", instance, i);
|
||||
|
||||
sp810->timerclken[i].sp810 = sp810;
|
||||
sp810->timerclken[i].channel = i;
|
||||
|
@ -184,5 +185,6 @@ void __init clk_sp810_of_setup(struct device_node *node)
|
|||
}
|
||||
|
||||
of_clk_add_provider(node, clk_sp810_timerclken_of_get, sp810);
|
||||
instance++;
|
||||
}
|
||||
CLK_OF_DECLARE(sp810, "arm,sp810", clk_sp810_of_setup);
|
||||
|
|
|
@ -1037,8 +1037,11 @@ static int intel_pstate_cpu_init(struct cpufreq_policy *policy)
|
|||
|
||||
/* cpuinfo and default policy values */
|
||||
policy->cpuinfo.min_freq = cpu->pstate.min_pstate * cpu->pstate.scaling;
|
||||
policy->cpuinfo.max_freq =
|
||||
cpu->pstate.turbo_pstate * cpu->pstate.scaling;
|
||||
update_turbo_state();
|
||||
policy->cpuinfo.max_freq = limits.turbo_disabled ?
|
||||
cpu->pstate.max_pstate : cpu->pstate.turbo_pstate;
|
||||
policy->cpuinfo.max_freq *= cpu->pstate.scaling;
|
||||
|
||||
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
|
||||
cpumask_set_cpu(policy->cpu, policy->cpus);
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
|
|||
struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
|
||||
struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
|
||||
unsigned int unit;
|
||||
u32 unit_size;
|
||||
int ret;
|
||||
|
||||
if (!ctx->u.aes.key_len)
|
||||
|
@ -133,11 +134,17 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
|
|||
if (!req->info)
|
||||
return -EINVAL;
|
||||
|
||||
for (unit = 0; unit < ARRAY_SIZE(unit_size_map); unit++)
|
||||
if (!(req->nbytes & (unit_size_map[unit].size - 1)))
|
||||
break;
|
||||
unit_size = CCP_XTS_AES_UNIT_SIZE__LAST;
|
||||
if (req->nbytes <= unit_size_map[0].size) {
|
||||
for (unit = 0; unit < ARRAY_SIZE(unit_size_map); unit++) {
|
||||
if (!(req->nbytes & (unit_size_map[unit].size - 1))) {
|
||||
unit_size = unit_size_map[unit].value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((unit_size_map[unit].value == CCP_XTS_AES_UNIT_SIZE__LAST) ||
|
||||
if ((unit_size == CCP_XTS_AES_UNIT_SIZE__LAST) ||
|
||||
(ctx->u.aes.key_len != AES_KEYSIZE_128)) {
|
||||
/* Use the fallback to process the request for any
|
||||
* unsupported unit sizes or key sizes
|
||||
|
@ -158,7 +165,7 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
|
|||
rctx->cmd.engine = CCP_ENGINE_XTS_AES_128;
|
||||
rctx->cmd.u.xts.action = (encrypt) ? CCP_AES_ACTION_ENCRYPT
|
||||
: CCP_AES_ACTION_DECRYPT;
|
||||
rctx->cmd.u.xts.unit_size = unit_size_map[unit].value;
|
||||
rctx->cmd.u.xts.unit_size = unit_size;
|
||||
rctx->cmd.u.xts.key = &ctx->u.aes.key_sg;
|
||||
rctx->cmd.u.xts.key_len = ctx->u.aes.key_len;
|
||||
rctx->cmd.u.xts.iv = &rctx->iv_sg;
|
||||
|
|
|
@ -797,7 +797,7 @@ static int hash_process_data(struct hash_device_data *device_data,
|
|||
&device_data->state);
|
||||
memmove(req_ctx->state.buffer,
|
||||
device_data->state.buffer,
|
||||
HASH_BLOCK_SIZE / sizeof(u32));
|
||||
HASH_BLOCK_SIZE);
|
||||
if (ret) {
|
||||
dev_err(device_data->dev,
|
||||
"%s: hash_resume_state() failed!\n",
|
||||
|
@ -848,7 +848,7 @@ static int hash_process_data(struct hash_device_data *device_data,
|
|||
|
||||
memmove(device_data->state.buffer,
|
||||
req_ctx->state.buffer,
|
||||
HASH_BLOCK_SIZE / sizeof(u32));
|
||||
HASH_BLOCK_SIZE);
|
||||
if (ret) {
|
||||
dev_err(device_data->dev, "%s: hash_save_state() failed!\n",
|
||||
__func__);
|
||||
|
|
|
@ -167,7 +167,7 @@ struct crypto_alg p8_aes_cbc_alg = {
|
|||
.cra_name = "cbc(aes)",
|
||||
.cra_driver_name = "p8_aes_cbc",
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_priority = 1000,
|
||||
.cra_priority = 2000,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_alignmask = 0,
|
||||
|
|
|
@ -151,7 +151,7 @@ struct crypto_alg p8_aes_ctr_alg = {
|
|||
.cra_name = "ctr(aes)",
|
||||
.cra_driver_name = "p8_aes_ctr",
|
||||
.cra_module = THIS_MODULE,
|
||||
.cra_priority = 1000,
|
||||
.cra_priority = 2000,
|
||||
.cra_type = &crypto_blkcipher_type,
|
||||
.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_NEED_FALLBACK,
|
||||
.cra_alignmask = 0,
|
||||
|
|
|
@ -238,7 +238,7 @@ struct at_xdmac_lld {
|
|||
u32 mbr_cfg; /* Configuration Register */
|
||||
};
|
||||
|
||||
|
||||
/* 64-bit alignment needed to update CNDA and CUBC registers in an atomic way. */
|
||||
struct at_xdmac_desc {
|
||||
struct at_xdmac_lld lld;
|
||||
enum dma_transfer_direction direction;
|
||||
|
@ -249,7 +249,7 @@ struct at_xdmac_desc {
|
|||
unsigned int xfer_size;
|
||||
struct list_head descs_list;
|
||||
struct list_head xfer_node;
|
||||
};
|
||||
} __aligned(sizeof(u64));
|
||||
|
||||
static inline void __iomem *at_xdmac_chan_reg_base(struct at_xdmac *atxdmac, unsigned int chan_nb)
|
||||
{
|
||||
|
@ -930,6 +930,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
|
|||
u32 cur_nda, check_nda, cur_ubc, mask, value;
|
||||
u8 dwidth = 0;
|
||||
unsigned long flags;
|
||||
bool initd;
|
||||
|
||||
ret = dma_cookie_status(chan, cookie, txstate);
|
||||
if (ret == DMA_COMPLETE)
|
||||
|
@ -954,7 +955,16 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
|
|||
residue = desc->xfer_size;
|
||||
/*
|
||||
* Flush FIFO: only relevant when the transfer is source peripheral
|
||||
* synchronized.
|
||||
* synchronized. Flush is needed before reading CUBC because data in
|
||||
* the FIFO are not reported by CUBC. Reporting a residue of the
|
||||
* transfer length while we have data in FIFO can cause issue.
|
||||
* Usecase: atmel USART has a timeout which means I have received
|
||||
* characters but there is no more character received for a while. On
|
||||
* timeout, it requests the residue. If the data are in the DMA FIFO,
|
||||
* we will return a residue of the transfer length. It means no data
|
||||
* received. If an application is waiting for these data, it will hang
|
||||
* since we won't have another USART timeout without receiving new
|
||||
* data.
|
||||
*/
|
||||
mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC;
|
||||
value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM;
|
||||
|
@ -965,34 +975,43 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
|
|||
}
|
||||
|
||||
/*
|
||||
* When processing the residue, we need to read two registers but we
|
||||
* can't do it in an atomic way. AT_XDMAC_CNDA is used to find where
|
||||
* we stand in the descriptor list and AT_XDMAC_CUBC is used
|
||||
* to know how many data are remaining for the current descriptor.
|
||||
* Since the dma channel is not paused to not loose data, between the
|
||||
* AT_XDMAC_CNDA and AT_XDMAC_CUBC read, we may have change of
|
||||
* descriptor.
|
||||
* For that reason, after reading AT_XDMAC_CUBC, we check if we are
|
||||
* still using the same descriptor by reading a second time
|
||||
* AT_XDMAC_CNDA. If AT_XDMAC_CNDA has changed, it means we have to
|
||||
* read again AT_XDMAC_CUBC.
|
||||
* The easiest way to compute the residue should be to pause the DMA
|
||||
* but doing this can lead to miss some data as some devices don't
|
||||
* have FIFO.
|
||||
* We need to read several registers because:
|
||||
* - DMA is running therefore a descriptor change is possible while
|
||||
* reading these registers
|
||||
* - When the block transfer is done, the value of the CUBC register
|
||||
* is set to its initial value until the fetch of the next descriptor.
|
||||
* This value will corrupt the residue calculation so we have to skip
|
||||
* it.
|
||||
*
|
||||
* INITD -------- ------------
|
||||
* |____________________|
|
||||
* _______________________ _______________
|
||||
* NDA @desc2 \/ @desc3
|
||||
* _______________________/\_______________
|
||||
* __________ ___________ _______________
|
||||
* CUBC 0 \/ MAX desc1 \/ MAX desc2
|
||||
* __________/\___________/\_______________
|
||||
*
|
||||
* Since descriptors are aligned on 64 bits, we can assume that
|
||||
* the update of NDA and CUBC is atomic.
|
||||
* Memory barriers are used to ensure the read order of the registers.
|
||||
* A max number of retries is set because unlikely it can never ends if
|
||||
* we are transferring a lot of data with small buffers.
|
||||
* A max number of retries is set because unlikely it could never ends.
|
||||
*/
|
||||
cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
|
||||
rmb();
|
||||
cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC);
|
||||
for (retry = 0; retry < AT_XDMAC_RESIDUE_MAX_RETRIES; retry++) {
|
||||
rmb();
|
||||
check_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
|
||||
|
||||
if (likely(cur_nda == check_nda))
|
||||
break;
|
||||
|
||||
cur_nda = check_nda;
|
||||
rmb();
|
||||
initd = !!(at_xdmac_chan_read(atchan, AT_XDMAC_CC) & AT_XDMAC_CC_INITD);
|
||||
rmb();
|
||||
cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC);
|
||||
rmb();
|
||||
cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
|
||||
rmb();
|
||||
|
||||
if ((check_nda == cur_nda) && initd)
|
||||
break;
|
||||
}
|
||||
|
||||
if (unlikely(retry >= AT_XDMAC_RESIDUE_MAX_RETRIES)) {
|
||||
|
@ -1000,6 +1019,19 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
|
|||
goto spin_unlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush FIFO: only relevant when the transfer is source peripheral
|
||||
* synchronized. Another flush is needed here because CUBC is updated
|
||||
* when the controller sends the data write command. It can lead to
|
||||
* report data that are not written in the memory or the device. The
|
||||
* FIFO flush ensures that data are really written.
|
||||
*/
|
||||
if ((desc->lld.mbr_cfg & mask) == value) {
|
||||
at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask);
|
||||
while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS))
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove size of all microblocks already transferred and the current
|
||||
* one. Then add the remaining size to transfer of the current
|
||||
|
|
|
@ -218,8 +218,11 @@ static const u32 rir_offset[MAX_RIR_RANGES][MAX_RIR_WAY] = {
|
|||
{ 0x1a0, 0x1a4, 0x1a8, 0x1ac, 0x1b0, 0x1b4, 0x1b8, 0x1bc },
|
||||
};
|
||||
|
||||
#define RIR_RNK_TGT(reg) GET_BITFIELD(reg, 16, 19)
|
||||
#define RIR_OFFSET(reg) GET_BITFIELD(reg, 2, 14)
|
||||
#define RIR_RNK_TGT(type, reg) (((type) == BROADWELL) ? \
|
||||
GET_BITFIELD(reg, 20, 23) : GET_BITFIELD(reg, 16, 19))
|
||||
|
||||
#define RIR_OFFSET(type, reg) (((type) == HASWELL || (type) == BROADWELL) ? \
|
||||
GET_BITFIELD(reg, 2, 15) : GET_BITFIELD(reg, 2, 14))
|
||||
|
||||
/* Device 16, functions 2-7 */
|
||||
|
||||
|
@ -1101,14 +1104,14 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
|
|||
pci_read_config_dword(pvt->pci_tad[i],
|
||||
rir_offset[j][k],
|
||||
®);
|
||||
tmp_mb = RIR_OFFSET(reg) << 6;
|
||||
tmp_mb = RIR_OFFSET(pvt->info.type, reg) << 6;
|
||||
|
||||
gb = div_u64_rem(tmp_mb, 1024, &mb);
|
||||
edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n",
|
||||
i, j, k,
|
||||
gb, (mb*1000)/1024,
|
||||
((u64)tmp_mb) << 20L,
|
||||
(u32)RIR_RNK_TGT(reg),
|
||||
(u32)RIR_RNK_TGT(pvt->info.type, reg),
|
||||
reg);
|
||||
}
|
||||
}
|
||||
|
@ -1432,7 +1435,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
|
|||
pci_read_config_dword(pvt->pci_tad[base_ch],
|
||||
rir_offset[n_rir][idx],
|
||||
®);
|
||||
*rank = RIR_RNK_TGT(reg);
|
||||
*rank = RIR_RNK_TGT(pvt->info.type, reg);
|
||||
|
||||
edac_dbg(0, "RIR#%d: channel address 0x%08Lx < 0x%08Lx, RIR interleave %d, index %d\n",
|
||||
n_rir,
|
||||
|
|
|
@ -170,6 +170,7 @@ static int generic_ops_register(void)
|
|||
{
|
||||
generic_ops.get_variable = efi.get_variable;
|
||||
generic_ops.set_variable = efi.set_variable;
|
||||
generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking;
|
||||
generic_ops.get_next_variable = efi.get_next_variable;
|
||||
generic_ops.query_variable_store = efi_query_variable_store;
|
||||
|
||||
|
|
|
@ -549,11 +549,11 @@ static void bcm_kona_gpio_reset(struct bcm_kona_gpio *kona_gpio)
|
|||
/* disable interrupts and clear status */
|
||||
for (i = 0; i < kona_gpio->num_bank; i++) {
|
||||
/* Unlock the entire bank first */
|
||||
bcm_kona_gpio_write_lock_regs(kona_gpio, i, UNLOCK_CODE);
|
||||
bcm_kona_gpio_write_lock_regs(reg_base, i, UNLOCK_CODE);
|
||||
writel(0xffffffff, reg_base + GPIO_INT_MASK(i));
|
||||
writel(0xffffffff, reg_base + GPIO_INT_STATUS(i));
|
||||
/* Now re-lock the bank */
|
||||
bcm_kona_gpio_write_lock_regs(kona_gpio, i, LOCK_CODE);
|
||||
bcm_kona_gpio_write_lock_regs(reg_base, i, LOCK_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -375,7 +375,7 @@ struct gpio_chip *gpiochip_find(void *data,
|
|||
|
||||
spin_lock_irqsave(&gpio_lock, flags);
|
||||
list_for_each_entry(chip, &gpio_chips, list)
|
||||
if (match(chip, data))
|
||||
if (chip && match(chip, data))
|
||||
break;
|
||||
|
||||
/* No match? */
|
||||
|
|
|
@ -335,6 +335,8 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
|
|||
|
||||
atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff,
|
||||
factor_reg);
|
||||
} else {
|
||||
atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -432,7 +432,7 @@ static u32 drm_dp_i2c_functionality(struct i2c_adapter *adapter)
|
|||
*/
|
||||
static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
|
||||
{
|
||||
unsigned int retry;
|
||||
unsigned int retry, defer_i2c;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
@ -440,7 +440,7 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
|
|||
* is required to retry at least seven times upon receiving AUX_DEFER
|
||||
* before giving up the AUX transaction.
|
||||
*/
|
||||
for (retry = 0; retry < 7; retry++) {
|
||||
for (retry = 0, defer_i2c = 0; retry < (7 + defer_i2c); retry++) {
|
||||
mutex_lock(&aux->hw_mutex);
|
||||
ret = aux->transfer(aux, msg);
|
||||
mutex_unlock(&aux->hw_mutex);
|
||||
|
@ -499,7 +499,13 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
|
|||
|
||||
case DP_AUX_I2C_REPLY_DEFER:
|
||||
DRM_DEBUG_KMS("I2C defer\n");
|
||||
/* DP Compliance Test 4.2.2.5 Requirement:
|
||||
* Must have at least 7 retries for I2C defers on the
|
||||
* transaction to pass this test
|
||||
*/
|
||||
aux->i2c_defer_count++;
|
||||
if (defer_i2c < 7)
|
||||
defer_i2c++;
|
||||
usleep_range(400, 500);
|
||||
continue;
|
||||
|
||||
|
|
|
@ -2862,11 +2862,9 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
|
|||
drm_dp_port_teardown_pdt(port, port->pdt);
|
||||
|
||||
if (!port->input && port->vcpi.vcpi > 0) {
|
||||
if (mgr->mst_state) {
|
||||
drm_dp_mst_reset_vcpi_slots(mgr, port);
|
||||
drm_dp_update_payload_part1(mgr);
|
||||
drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
|
||||
}
|
||||
drm_dp_mst_reset_vcpi_slots(mgr, port);
|
||||
drm_dp_update_payload_part1(mgr);
|
||||
drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
|
||||
}
|
||||
|
||||
kref_put(&port->kref, drm_dp_free_mst_port);
|
||||
|
|
|
@ -7129,12 +7129,14 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
|
|||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_encoder *encoder;
|
||||
int i;
|
||||
u32 val, final;
|
||||
bool has_lvds = false;
|
||||
bool has_cpu_edp = false;
|
||||
bool has_panel = false;
|
||||
bool has_ck505 = false;
|
||||
bool can_ssc = false;
|
||||
bool using_ssc_source = false;
|
||||
|
||||
/* We need to take the global config into account */
|
||||
for_each_intel_encoder(dev, encoder) {
|
||||
|
@ -7161,8 +7163,22 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
|
|||
can_ssc = true;
|
||||
}
|
||||
|
||||
DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d\n",
|
||||
has_panel, has_lvds, has_ck505);
|
||||
/* Check if any DPLLs are using the SSC source */
|
||||
for (i = 0; i < dev_priv->num_shared_dpll; i++) {
|
||||
u32 temp = I915_READ(PCH_DPLL(i));
|
||||
|
||||
if (!(temp & DPLL_VCO_ENABLE))
|
||||
continue;
|
||||
|
||||
if ((temp & PLL_REF_INPUT_MASK) ==
|
||||
PLLB_REF_INPUT_SPREADSPECTRUMIN) {
|
||||
using_ssc_source = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n",
|
||||
has_panel, has_lvds, has_ck505, using_ssc_source);
|
||||
|
||||
/* Ironlake: try to setup display ref clock before DPLL
|
||||
* enabling. This is only under driver's control after
|
||||
|
@ -7199,9 +7215,9 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
|
|||
final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
|
||||
} else
|
||||
final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
|
||||
} else {
|
||||
final |= DREF_SSC_SOURCE_DISABLE;
|
||||
final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
|
||||
} else if (using_ssc_source) {
|
||||
final |= DREF_SSC_SOURCE_ENABLE;
|
||||
final |= DREF_SSC1_ENABLE;
|
||||
}
|
||||
|
||||
if (final == val)
|
||||
|
@ -7247,7 +7263,7 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
|
|||
POSTING_READ(PCH_DREF_CONTROL);
|
||||
udelay(200);
|
||||
} else {
|
||||
DRM_DEBUG_KMS("Disabling SSC entirely\n");
|
||||
DRM_DEBUG_KMS("Disabling CPU source output\n");
|
||||
|
||||
val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
|
||||
|
||||
|
@ -7258,16 +7274,20 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
|
|||
POSTING_READ(PCH_DREF_CONTROL);
|
||||
udelay(200);
|
||||
|
||||
/* Turn off the SSC source */
|
||||
val &= ~DREF_SSC_SOURCE_MASK;
|
||||
val |= DREF_SSC_SOURCE_DISABLE;
|
||||
if (!using_ssc_source) {
|
||||
DRM_DEBUG_KMS("Disabling SSC source\n");
|
||||
|
||||
/* Turn off SSC1 */
|
||||
val &= ~DREF_SSC1_ENABLE;
|
||||
/* Turn off the SSC source */
|
||||
val &= ~DREF_SSC_SOURCE_MASK;
|
||||
val |= DREF_SSC_SOURCE_DISABLE;
|
||||
|
||||
I915_WRITE(PCH_DREF_CONTROL, val);
|
||||
POSTING_READ(PCH_DREF_CONTROL);
|
||||
udelay(200);
|
||||
/* Turn off SSC1 */
|
||||
val &= ~DREF_SSC1_ENABLE;
|
||||
|
||||
I915_WRITE(PCH_DREF_CONTROL, val);
|
||||
POSTING_READ(PCH_DREF_CONTROL);
|
||||
udelay(200);
|
||||
}
|
||||
}
|
||||
|
||||
BUG_ON(val != final);
|
||||
|
|
|
@ -1814,6 +1814,17 @@ i915_dispatch_execbuffer(struct intel_engine_cs *ring,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void cleanup_phys_status_page(struct intel_engine_cs *ring)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = to_i915(ring->dev);
|
||||
|
||||
if (!dev_priv->status_page_dmah)
|
||||
return;
|
||||
|
||||
drm_pci_free(ring->dev, dev_priv->status_page_dmah);
|
||||
ring->status_page.page_addr = NULL;
|
||||
}
|
||||
|
||||
static void cleanup_status_page(struct intel_engine_cs *ring)
|
||||
{
|
||||
struct drm_i915_gem_object *obj;
|
||||
|
@ -1830,9 +1841,9 @@ static void cleanup_status_page(struct intel_engine_cs *ring)
|
|||
|
||||
static int init_status_page(struct intel_engine_cs *ring)
|
||||
{
|
||||
struct drm_i915_gem_object *obj;
|
||||
struct drm_i915_gem_object *obj = ring->status_page.obj;
|
||||
|
||||
if ((obj = ring->status_page.obj) == NULL) {
|
||||
if (obj == NULL) {
|
||||
unsigned flags;
|
||||
int ret;
|
||||
|
||||
|
@ -1985,7 +1996,7 @@ static int intel_init_ring_buffer(struct drm_device *dev,
|
|||
if (ret)
|
||||
goto error;
|
||||
} else {
|
||||
BUG_ON(ring->id != RCS);
|
||||
WARN_ON(ring->id != RCS);
|
||||
ret = init_phys_status_page(ring);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
@ -2049,7 +2060,12 @@ void intel_cleanup_ring_buffer(struct intel_engine_cs *ring)
|
|||
if (ring->cleanup)
|
||||
ring->cleanup(ring);
|
||||
|
||||
cleanup_status_page(ring);
|
||||
if (I915_NEED_GFX_HWS(ring->dev)) {
|
||||
cleanup_status_page(ring);
|
||||
} else {
|
||||
WARN_ON(ring->id != RCS);
|
||||
cleanup_phys_status_page(ring);
|
||||
}
|
||||
|
||||
i915_cmd_parser_fini_ring(ring);
|
||||
|
||||
|
|
|
@ -572,6 +572,8 @@ nouveau_fbcon_init(struct drm_device *dev)
|
|||
if (ret)
|
||||
goto fini;
|
||||
|
||||
if (fbcon->helper.fbdev)
|
||||
fbcon->helper.fbdev->pixmap.buf_align = 4;
|
||||
return 0;
|
||||
|
||||
fini:
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue