diff options
Diffstat (limited to 'arch/powerpc/kernel')
| -rw-r--r-- | arch/powerpc/kernel/cacheinfo.c | 3 | ||||
| -rw-r--r-- | arch/powerpc/kernel/cpu_setup_power.c | 43 | ||||
| -rw-r--r-- | arch/powerpc/kernel/cpu_specs_book3s_64.h | 36 | ||||
| -rw-r--r-- | arch/powerpc/kernel/dt_cpu_ftrs.c | 44 | ||||
| -rw-r--r-- | arch/powerpc/kernel/eeh_driver.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/head_64.S | 20 | ||||
| -rw-r--r-- | arch/powerpc/kernel/interrupt.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/iommu.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/irq.c | 16 | ||||
| -rw-r--r-- | arch/powerpc/kernel/pci-common.c | 9 | ||||
| -rw-r--r-- | arch/powerpc/kernel/prom.c | 1 | ||||
| -rw-r--r-- | arch/powerpc/kernel/prom_init.c | 46 | ||||
| -rw-r--r-- | arch/powerpc/kernel/rtas_flash.c | 27 | ||||
| -rw-r--r-- | arch/powerpc/kernel/rtas_pci.c | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/rtasd.c | 19 | ||||
| -rw-r--r-- | arch/powerpc/kernel/setup-common.c | 1 | ||||
| -rw-r--r-- | arch/powerpc/kernel/smp.c | 3 | ||||
| -rw-r--r-- | arch/powerpc/kernel/syscall.c | 10 | ||||
| -rw-r--r-- | arch/powerpc/kernel/syscalls/syscall.tbl | 1 | ||||
| -rw-r--r-- | arch/powerpc/kernel/vdso/gettimeofday.S | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/vdso/vdso32.lds.S | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/vdso/vgettimeofday.c | 16 |
22 files changed, 246 insertions, 79 deletions
diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index 04e5ea38bdc0..cb0933061006 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -690,7 +690,8 @@ show_shared_cpumap(struct kobject *k, struct kobj_attribute *attr, char *buf, bo mask = &cache->shared_cpu_map; - return cpumap_print_to_pagebuf(list, buf, mask); + return sysfs_emit(buf, list ? "%*pbl\n" : "%*pb\n", + cpumask_pr_args(mask)); } static ssize_t shared_cpu_map_show(struct kobject *k, struct kobj_attribute *attr, char *buf) diff --git a/arch/powerpc/kernel/cpu_setup_power.c b/arch/powerpc/kernel/cpu_setup_power.c index 98bd4e6c1770..5de704ac031d 100644 --- a/arch/powerpc/kernel/cpu_setup_power.c +++ b/arch/powerpc/kernel/cpu_setup_power.c @@ -286,3 +286,46 @@ void __restore_cpu_power10(void) init_HFSCR(); init_PMU_HV(); } + +void __setup_cpu_power12(unsigned long offset, struct cpu_spec *t) +{ + init_FSCR_power10(); + init_PMU(); + init_PMU_ISA31(); + + if (!init_hvmode_206(t)) + return; + + mtspr(SPRN_PSSCR, 0); + mtspr(SPRN_LPID, 0); + mtspr(SPRN_PID, 0); + mtspr(SPRN_AMOR, ~0); + mtspr(SPRN_PCR, PCR_MASK); + init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\ + LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0); + init_HFSCR(); + init_PMU_HV(); +} + +void __restore_cpu_power12(void) +{ + u64 msr; + + init_FSCR_power10(); + init_PMU(); + init_PMU_ISA31(); + + msr = mfmsr(); + if (!(msr & MSR_HV)) + return; + + mtspr(SPRN_PSSCR, 0); + mtspr(SPRN_LPID, 0); + mtspr(SPRN_PID, 0); + mtspr(SPRN_AMOR, ~0); + mtspr(SPRN_PCR, PCR_MASK); + init_LPCR_ISA300((mfspr(SPRN_LPCR) | LPCR_PECEDH | LPCR_PECE_HVEE |\ + LPCR_HVICE | LPCR_HEIC) & ~(LPCR_UPRT | LPCR_HR), 0); + init_HFSCR(); + init_PMU_HV(); +} diff --git a/arch/powerpc/kernel/cpu_specs_book3s_64.h b/arch/powerpc/kernel/cpu_specs_book3s_64.h index 98d4274a1b6b..26fa40aa34db 100644 --- a/arch/powerpc/kernel/cpu_specs_book3s_64.h +++ b/arch/powerpc/kernel/cpu_specs_book3s_64.h @@ -63,6 +63,11 @@ #define COMMON_USER_POWER11 COMMON_USER_POWER10 #define COMMON_USER2_POWER11 COMMON_USER2_POWER10 +#define COMMON_USER_POWER12 COMMON_USER_POWER10 +#define COMMON_USER2_POWER12 (COMMON_USER2_POWER10 | \ + PPC_FEATURE2_ARCH_3_2) + + static struct cpu_spec cpu_specs[] __initdata = { { /* PPC970 */ .pvr_mask = 0xffff0000, @@ -298,6 +303,20 @@ static struct cpu_spec cpu_specs[] __initdata = { .cpu_restore = __restore_cpu_power10, .platform = "power11", }, + { /* 3.2-compliant processor, i.e. Power12 "architected" mode */ + .pvr_mask = 0xffffffff, + .pvr_value = 0x0f000008, + .cpu_name = "Power12 (architected)", + .cpu_features = CPU_FTRS_POWER12, + .cpu_user_features = COMMON_USER_POWER12, + .cpu_user_features2 = COMMON_USER2_POWER12, + .mmu_features = MMU_FTRS_POWER12, + .icache_bsize = 128, + .dcache_bsize = 128, + .cpu_setup = __setup_cpu_power12, + .cpu_restore = __restore_cpu_power12, + .platform = "power12", + }, { /* Power7 */ .pvr_mask = 0xffff0000, .pvr_value = 0x003f0000, @@ -485,6 +504,23 @@ static struct cpu_spec cpu_specs[] __initdata = { .machine_check_early = __machine_check_early_realmode_p10, .platform = "power11", }, + { /* Power12 */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x00830000, + .cpu_name = "Power12 (raw)", + .cpu_features = CPU_FTRS_POWER12, + .cpu_user_features = COMMON_USER_POWER12, + .cpu_user_features2 = COMMON_USER2_POWER12, + .mmu_features = MMU_FTRS_POWER12, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 6, + .pmc_type = PPC_PMC_IBM, + .cpu_setup = __setup_cpu_power12, + .cpu_restore = __restore_cpu_power12, + .machine_check_early = __machine_check_early_realmode_p10, + .platform = "power12", + }, { /* Cell Broadband Engine */ .pvr_mask = 0xffff0000, .pvr_value = 0x00700000, diff --git a/arch/powerpc/kernel/dt_cpu_ftrs.c b/arch/powerpc/kernel/dt_cpu_ftrs.c index e5853daa6a48..a87b22f555b2 100644 --- a/arch/powerpc/kernel/dt_cpu_ftrs.c +++ b/arch/powerpc/kernel/dt_cpu_ftrs.c @@ -26,6 +26,7 @@ /* Device-tree visible constants follow */ #define ISA_V3_0B 3000 #define ISA_V3_1 3100 +#define ISA_V3_2 3200 #define USABLE_PR (1U << 0) #define USABLE_OS (1U << 1) @@ -90,8 +91,6 @@ static void __restore_cpu_cpufeatures(void) init_pmu_registers(); } -static char dt_cpu_name[64]; - static struct cpu_spec __initdata base_cpu_spec = { .cpu_name = NULL, .cpu_features = CPU_FTRS_DT_CPU_BASE, @@ -466,6 +465,35 @@ static int __init feat_enable_mce_power11(struct dt_cpu_feature *f) return 1; } +static void init_pmu_power12(void) +{ + init_pmu_power10(); +} + +static int __init feat_enable_pmu_power12(struct dt_cpu_feature *f) +{ + hfscr_pmu_enable(); + + init_pmu_power12(); + init_pmu_registers = init_pmu_power12; + + cur_cpu_spec->cpu_features |= CPU_FTR_MMCRA; + cur_cpu_spec->cpu_user_features |= PPC_FEATURE_PSERIES_PERFMON_COMPAT; + + cur_cpu_spec->num_pmcs = 6; + cur_cpu_spec->pmc_type = PPC_PMC_IBM; + + return 1; +} + +static int __init feat_enable_mce_power12(struct dt_cpu_feature *f) +{ + cur_cpu_spec->platform = "power12"; + cur_cpu_spec->machine_check_early = __machine_check_early_realmode_p10; + + return 1; +} + static int __init feat_enable_tm(struct dt_cpu_feature *f) { #ifdef CONFIG_PPC_TRANSACTIONAL_MEM @@ -657,9 +685,11 @@ static struct dt_cpu_feature_match __initdata {"machine-check-power9", feat_enable_mce_power9, 0}, {"machine-check-power10", feat_enable_mce_power10, 0}, {"machine-check-power11", feat_enable_mce_power11, 0}, + {"machine-check-power12", feat_enable_mce_power12, 0}, {"performance-monitor-power9", feat_enable_pmu_power9, 0}, {"performance-monitor-power10", feat_enable_pmu_power10, 0}, {"performance-monitor-power11", feat_enable_pmu_power10, 0}, + {"performance-monitor-power12", feat_enable_pmu_power12, 0}, {"event-based-branch-v3", feat_enable, 0}, {"random-number-generator", feat_enable, 0}, {"system-call-vectored", feat_disable, 0}, @@ -714,6 +744,11 @@ static void __init cpufeatures_setup_start(u32 isa) if (PVR_VER(mfspr(SPRN_PVR)) >= PVR_POWER11) cur_cpu_spec->cpu_features |= CPU_FTR_P11_PVR; } + + if (isa >= ISA_V3_2) { + cur_cpu_spec->cpu_features |= CPU_FTR_ARCH_32; + cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_ARCH_3_2; + } } static bool __init cpufeatures_process_feature(struct dt_cpu_feature *f) @@ -1078,6 +1113,7 @@ static int __init count_cpufeatures_subnodes(unsigned long node, static int __init dt_cpu_ftrs_scan_callback(unsigned long node, const char *uname, int depth, void *data) { + static char dt_cpu_name[64]; const __be32 *prop; int count, i; u32 isa; @@ -1115,8 +1151,8 @@ static int __init dt_cpu_ftrs_scan_callback(unsigned long node, const char } prop = of_get_flat_dt_prop(node, "display-name", NULL); - if (prop && strlen((char *)prop) != 0) { - strscpy(dt_cpu_name, (char *)prop, sizeof(dt_cpu_name)); + if (prop && *(char *)prop != 0) { + strscpy(dt_cpu_name, (char *)prop); cur_cpu_spec->cpu_name = dt_cpu_name; } diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c index 028f69158532..d64cce17a4e0 100644 --- a/arch/powerpc/kernel/eeh_driver.c +++ b/arch/powerpc/kernel/eeh_driver.c @@ -533,9 +533,7 @@ static void eeh_rmv_device(struct eeh_dev *edev, void *userdata) if (rmv_data) list_add(&edev->rmv_entry, &rmv_data->removed_vf_list); } else { - pci_lock_rescan_remove(); pci_stop_and_remove_bus_device(dev); - pci_unlock_rescan_remove(); } } diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 63432a33ec49..a54f6f979173 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -713,14 +713,18 @@ p_end: .8byte _end - copy_to_here _GLOBAL(copy_and_flush) addi r5,r5,-8 addi r6,r6,-8 -4: li r0,8 /* Use the smallest common */ - /* denominator cache line */ - /* size. This results in */ - /* extra cache line flushes */ - /* but operation is correct. */ - /* Can't get cache line size */ - /* from NACA as it is being */ - /* moved too. */ +4: li r0,8 /* r0 is the number of 8-byte words */ + /* to copy per cache sync iteration. */ + /* 8 words * 8 bytes = 64 bytes. 64B is */ + /* the current default cache line size. */ + /* This is a loop count, not a byte */ + /* count. Increasing it may skip */ + /* dcbst/icbi for lines in between and */ + /* leave stale instructions in icache. */ + /* This results in extra cache line */ + /* flushes but operation is correct. */ + /* Can't get cache line size from NACA */ + /* as it is being moved too. */ mtctr r0 /* put # words/line in ctr */ 3: addi r6,r6,8 /* copy a cache line */ diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c index 5b88bf72786c..55f9c0c9922a 100644 --- a/arch/powerpc/kernel/interrupt.c +++ b/arch/powerpc/kernel/interrupt.c @@ -175,7 +175,7 @@ again: current_thread_info()->exit_flags &= ~_TIF_RESTOREALL; regs->exit_result |= ret; - return ret; + return regs->exit_result; } #endif diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index ee1b5cb557c9..1ae8384637b5 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -1076,7 +1076,7 @@ int iommu_tce_check_ioba(unsigned long page_shift, if (ioba < offset) return -EINVAL; - if ((ioba + 1) > (offset + size)) + if ((ioba + npages < ioba) || (ioba - offset + npages > size)) return -EINVAL; return 0; diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index f69de08ad347..15a3c3fd8e70 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -217,8 +217,12 @@ static __always_inline void call_do_softirq(const void *sp) [sp] "b" (sp), [offset] "i" (THREAD_SIZE - STACK_FRAME_MIN_SIZE), [callee] "i" (__do_softirq) : // Clobbers - "lr", "xer", "ctr", "memory", "cr0", "cr1", "cr5", "cr6", - "cr7", "r0", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "lr", "xer", "ctr", "memory", "cr0", "cr1", "cr5", "cr6", "cr7", "r0", + /* r2 may be clobbered by the callee when using PCREL mode in the ELFv2 ABI. */ +#ifdef CONFIG_PPC_KERNEL_PCREL + "r2", +#endif + "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); } @@ -275,8 +279,12 @@ static __always_inline void call_do_irq(struct pt_regs *regs, void *sp) [sp] "b" (sp), [offset] "i" (THREAD_SIZE - STACK_FRAME_MIN_SIZE), [callee] "i" (__do_irq) : // Clobbers - "lr", "xer", "ctr", "memory", "cr0", "cr1", "cr5", "cr6", - "cr7", "r0", "r4", "r5", "r6", "r7", "r8", "r9", "r10", + "lr", "xer", "ctr", "memory", "cr0", "cr1", "cr5", "cr6", "cr7", "r0", + /* r2 may be clobbered by the callee when using PCREL mode in the ELFv2 ABI. */ +#ifdef CONFIG_PPC_KERNEL_PCREL + "r2", +#endif + "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12" ); } diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c index 3c4ca90e2ab7..4fc52c21fe5d 100644 --- a/arch/powerpc/kernel/pci-common.c +++ b/arch/powerpc/kernel/pci-common.c @@ -626,19 +626,14 @@ int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size) return -ENXIO; addr = hose->io_base_virt + port; - /* WARNING: The generic code is idiotic. It gets passed a pointer - * to what can be a 1, 2 or 4 byte quantity and always reads that - * as a u32, which means that we have to correct the location of - * the data read within those 32 bits for size 1 and 2 - */ switch(size) { case 1: - out_8(addr, val >> 24); + out_8(addr, val); return 1; case 2: if (port & 1) return -EINVAL; - out_le16(addr, val >> 16); + out_le16(addr, val); return 2; case 4: if (port & 3) diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 9ed9dde7d231..d218c8cc1f73 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -824,7 +824,6 @@ void __init early_init_devtree(void *params) fadump_append_bootargs(); /* Scan memory nodes and rebuild MEMBLOCKs */ - early_init_dt_scan_root(); early_init_dt_scan_memory_ppc(); /* diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 53503937de0e..eb9f556b0937 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -86,6 +86,12 @@ */ #define ADDR(x) (u32)(unsigned long)(x) +/* + * Current Power system firmware caps the PVR list array size at 16 entries + * during CAS (Client Architecture Support) negotiation. + */ +#define CAS_MAX_PVR_ENTRIES 16 + #ifdef CONFIG_PPC64 #define OF_WORKAROUNDS 0 #else @@ -947,7 +953,7 @@ struct option_vector7 { } __packed; struct ibm_arch_vec { - struct { __be32 mask, val; } pvrs[16]; + struct { __be32 mask, val; } pvrs[18]; u8 num_vectors; @@ -980,6 +986,10 @@ static const struct ibm_arch_vec ibm_architecture_vec_template __initconst = { .val = cpu_to_be32(0x003a0000), }, { + .mask = cpu_to_be32(0xffffffff), /* all 2.04-compliant and earlier */ + .val = cpu_to_be32(0x0f000001), + }, + { .mask = cpu_to_be32(0xffff0000), /* POWER6 */ .val = cpu_to_be32(0x003e0000), }, @@ -1012,6 +1022,14 @@ static const struct ibm_arch_vec ibm_architecture_vec_template __initconst = { .val = cpu_to_be32(0x00820000), }, { + .mask = cpu_to_be32(0xffff0000), /* POWER12 */ + .val = cpu_to_be32(0x00830000), + }, + { + .mask = cpu_to_be32(0xffffffff), /* all 3.2-compliant */ + .val = cpu_to_be32(0x0f000008), + }, + { .mask = cpu_to_be32(0xffffffff), /* P11 compliant */ .val = cpu_to_be32(0x0f000007), }, @@ -1032,13 +1050,9 @@ static const struct ibm_arch_vec ibm_architecture_vec_template __initconst = { .val = cpu_to_be32(0x0f000003), }, { - .mask = cpu_to_be32(0xffffffff), /* all 2.05-compliant */ + .mask = cpu_to_be32(0xfffffffd), /* all 2.05-compliant */ .val = cpu_to_be32(0x0f000002), }, - { - .mask = cpu_to_be32(0xfffffffe), /* all 2.04-compliant and earlier */ - .val = cpu_to_be32(0x0f000001), - }, }, .num_vectors = NUM_VECTORS(6), @@ -1048,7 +1062,7 @@ static const struct ibm_arch_vec ibm_architecture_vec_template __initconst = { .byte1 = 0, .arch_versions = OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 | OV1_PPC_2_04 | OV1_PPC_2_05 | OV1_PPC_2_06 | OV1_PPC_2_07, - .arch_versions3 = OV1_PPC_3_00 | OV1_PPC_3_1, + .arch_versions3 = OV1_PPC_3_00 | OV1_PPC_3_1 | OV1_PPC_3_2, }, .vec2_len = VECTOR_LENGTH(sizeof(struct option_vector2)), @@ -1403,6 +1417,22 @@ static void __init prom_send_capabilities(void) ihandle root; prom_arg_t ret; u32 cores; + int start_index = 0; + + /* + * Ensure that when running on Power11 or below hardware, the number + * of PVR entries passed during CAS negotiation does not exceed the + * firmware-imposed limit of 16. + * + * Compute the start_index to skip the oldest leading pvrs[] entries + * when running on Power11 or below hardware, so that the pointer + * passed to ibm,client-architecture-support points to + * ibm_architecture_vec.pvrs[start_index], presenting exactly 16 + * entries to firmware. + */ + if ((ARRAY_SIZE(ibm_architecture_vec_template.pvrs) > CAS_MAX_PVR_ENTRIES) && + (PVR_VER(mfspr(SPRN_PVR)) <= PVR_POWER11)) + start_index = ARRAY_SIZE(ibm_architecture_vec_template.pvrs) - CAS_MAX_PVR_ENTRIES; /* Check ibm,arch-vec-5-platform-support and fixup vec5 if required */ prom_check_platform_support(); @@ -1427,7 +1457,7 @@ static void __init prom_send_capabilities(void) if (call_prom_ret("call-method", 3, 2, &ret, ADDR("ibm,client-architecture-support"), root, - ADDR(&ibm_architecture_vec)) == 0) { + ADDR(&ibm_architecture_vec.pvrs[start_index])) == 0) { /* the call exists... */ if (ret) prom_printf("\nWARNING: ibm,client-architecture" diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index 583dc16e9d3c..722dbfb6fbf8 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -394,30 +394,23 @@ static ssize_t manage_flash_write(struct file *file, const char __user *buf, size_t count, loff_t *off) { struct rtas_manage_flash_t *const args_buf = &rtas_manage_flash_data; - static const char reject_str[] = "0"; - static const char commit_str[] = "1"; - char stkbuf[10]; - int op; + unsigned int op; + char cmd; guard(mutex)(&rtas_manage_flash_mutex); if ((args_buf->status == MANAGE_AUTH) || (count == 0)) return count; - op = -1; - if (buf) { - if (count > 9) count = 9; - if (copy_from_user (stkbuf, buf, count)) - return -EFAULT; - if (strncmp(stkbuf, reject_str, strlen(reject_str)) == 0) - op = RTAS_REJECT_TMP_IMG; - else if (strncmp(stkbuf, commit_str, strlen(commit_str)) == 0) - op = RTAS_COMMIT_TMP_IMG; - } - - if (op == -1) { /* buf is empty, or contains invalid string */ + if (get_user(cmd, buf)) + return -EFAULT; + + if (cmd == '0') + op = RTAS_REJECT_TMP_IMG; + else if (cmd == '1') + op = RTAS_COMMIT_TMP_IMG; + else return -EINVAL; - } manage_flash(args_buf, op); return count; diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c index fccf96e897f6..206c825225c2 100644 --- a/arch/powerpc/kernel/rtas_pci.c +++ b/arch/powerpc/kernel/rtas_pci.c @@ -54,6 +54,10 @@ int rtas_pci_dn_read_config(struct pci_dn *pdn, int where, int size, u32 *val) if (!config_access_valid(pdn, where)) return PCIBIOS_BAD_REGISTER_NUMBER; #ifdef CONFIG_EEH + if (pdn->edev && + (pdn->edev->mode & EEH_DEV_REMOVED)) + return PCIBIOS_DEVICE_NOT_FOUND; + if (pdn->edev && pdn->edev->pe && (pdn->edev->pe->state & EEH_PE_CFG_BLOCKED)) return PCIBIOS_SET_FAILED; @@ -105,6 +109,10 @@ int rtas_pci_dn_write_config(struct pci_dn *pdn, int where, int size, u32 val) if (!config_access_valid(pdn, where)) return PCIBIOS_BAD_REGISTER_NUMBER; #ifdef CONFIG_EEH + if (pdn->edev && + (pdn->edev->mode & EEH_DEV_REMOVED)) + return PCIBIOS_DEVICE_NOT_FOUND; + if (pdn->edev && pdn->edev->pe && (pdn->edev->pe->state & EEH_PE_CFG_BLOCKED)) return PCIBIOS_SET_FAILED; diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c index 6336ec9aedd0..fd40864bdb70 100644 --- a/arch/powerpc/kernel/rtasd.c +++ b/arch/powerpc/kernel/rtasd.c @@ -10,6 +10,7 @@ #include <linux/sched.h> #include <linux/kernel.h> #include <linux/of.h> +#include <linux/overflow.h> #include <linux/poll.h> #include <linux/proc_fs.h> #include <linux/init.h> @@ -160,25 +161,17 @@ static void printk_log_rtas(char *buf, int len) static int log_rtas_len(char * buf) { - int len; + size_t len; struct rtas_error_log *err; - uint32_t extended_log_length; + u32 extended_log_length; - /* rtas fixed header */ - len = 8; err = (struct rtas_error_log *)buf; - extended_log_length = rtas_error_extended_log_length(err); - if (rtas_error_extended(err) && extended_log_length) { - - /* extended header */ - len += extended_log_length; - } + extended_log_length = rtas_error_extended(err) ? rtas_error_extended_log_length(err) : 0; + len = struct_size(err, buffer, extended_log_length); if (rtas_error_log_max == 0) rtas_error_log_max = rtas_get_error_log_max(); - - if (len > rtas_error_log_max) - len = rtas_error_log_max; + len = min(len, rtas_error_log_max); return len; } diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c index 67c545f61f0d..4afaba19b586 100644 --- a/arch/powerpc/kernel/setup-common.c +++ b/arch/powerpc/kernel/setup-common.c @@ -304,6 +304,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) break; case 0x004e: /* POWER9 bits 12-15 give chip type */ case 0x0080: /* POWER10 bit 12 gives SMT8/4 */ + case 0x0083: /* POWER12 bit 12 gives SMT8/4 */ maj = (pvr >> 8) & 0x0F; min = pvr & 0xFF; break; diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 3467f86fd78f..6a5a5469aaae 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -289,6 +289,9 @@ void smp_muxed_ipi_set_message(int cpu, int msg) void smp_muxed_ipi_message_pass(int cpu, int msg) { + if (!smp_ops->cause_ipi) + return; + smp_muxed_ipi_set_message(cpu, msg); /* diff --git a/arch/powerpc/kernel/syscall.c b/arch/powerpc/kernel/syscall.c index a9da2af6efa8..fbefe1927b10 100644 --- a/arch/powerpc/kernel/syscall.c +++ b/arch/powerpc/kernel/syscall.c @@ -2,7 +2,6 @@ #include <linux/compat.h> #include <linux/context_tracking.h> -#include <linux/randomize_kstack.h> #include <linux/entry-common.h> #include <asm/interrupt.h> @@ -19,8 +18,13 @@ notrace long system_call_exception(struct pt_regs *regs, unsigned long r0) long ret; syscall_fn f; - add_random_kstack_offset(); - r0 = syscall_enter_from_user_mode(regs, r0); + if (unlikely(!syscall_enter_from_user_mode_randomize_stack(regs, &r0))) { + clear_thread_flag(TIF_SYSCALL_RET); + return syscall_get_error(current, regs); + } + + if (unlikely(test_and_clear_thread_flag(TIF_SYSCALL_RET))) + return syscall_get_error(current, regs); if (unlikely(r0 >= NR_syscalls)) { if (unlikely(trap_is_unsupported_scv(regs))) { diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl index 4fcc7c58a105..cfbb70039ff0 100644 --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl @@ -562,3 +562,4 @@ 469 common file_setattr sys_file_setattr 470 common listns sys_listns 471 nospu rseq_slice_yield sys_rseq_slice_yield +472 common fchroot sys_fchroot diff --git a/arch/powerpc/kernel/vdso/gettimeofday.S b/arch/powerpc/kernel/vdso/gettimeofday.S index 1c8e51691bf8..c635cd1e77be 100644 --- a/arch/powerpc/kernel/vdso/gettimeofday.S +++ b/arch/powerpc/kernel/vdso/gettimeofday.S @@ -67,9 +67,11 @@ * int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); * */ +#if defined(__powerpc64__) || defined(CONFIG_COMPAT_32BIT_TIME) V_FUNCTION_BEGIN(__kernel_gettimeofday) cvdso_call __c_kernel_gettimeofday V_FUNCTION_END(__kernel_gettimeofday) +#endif /* * Exact prototype of clock_gettime() @@ -77,9 +79,11 @@ V_FUNCTION_END(__kernel_gettimeofday) * int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); * */ +#if defined(__powerpc64__) || defined(CONFIG_COMPAT_32BIT_TIME) V_FUNCTION_BEGIN(__kernel_clock_gettime) cvdso_call __c_kernel_clock_gettime V_FUNCTION_END(__kernel_clock_gettime) +#endif /* * Exact prototype of clock_gettime64() @@ -99,9 +103,11 @@ V_FUNCTION_END(__kernel_clock_gettime64) * int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); * */ +#if defined(__powerpc64__) || defined(CONFIG_COMPAT_32BIT_TIME) V_FUNCTION_BEGIN(__kernel_clock_getres) cvdso_call __c_kernel_clock_getres V_FUNCTION_END(__kernel_clock_getres) +#endif /* * Exact prototype of clock_getres_time64() @@ -122,6 +128,8 @@ V_FUNCTION_END(__kernel_clock_getres_time64) * time_t time(time *t); * */ +#if defined(__powerpc64__) || defined(CONFIG_COMPAT_32BIT_TIME) V_FUNCTION_BEGIN(__kernel_time) cvdso_call __c_kernel_time call_time=1 V_FUNCTION_END(__kernel_time) +#endif diff --git a/arch/powerpc/kernel/vdso/vdso32.lds.S b/arch/powerpc/kernel/vdso/vdso32.lds.S index 3f384a2526ae..5e87c18fd282 100644 --- a/arch/powerpc/kernel/vdso/vdso32.lds.S +++ b/arch/powerpc/kernel/vdso/vdso32.lds.S @@ -119,13 +119,15 @@ VERSION { VDSO_VERSION_STRING { global: - __kernel_get_syscall_map; +#ifdef CONFIG_COMPAT_32BIT_TIME __kernel_gettimeofday; __kernel_clock_gettime; - __kernel_clock_gettime64; __kernel_clock_getres; - __kernel_clock_getres_time64; __kernel_time; +#endif /* CONFIG_COMPAT_32BIT_TIME */ + __kernel_get_syscall_map; + __kernel_clock_gettime64; + __kernel_clock_getres_time64; __kernel_get_tbfreq; __kernel_sync_dicache; __kernel_sigtramp32; diff --git a/arch/powerpc/kernel/vdso/vgettimeofday.c b/arch/powerpc/kernel/vdso/vgettimeofday.c index 3c194e1ab562..4b712fb01a3f 100644 --- a/arch/powerpc/kernel/vdso/vgettimeofday.c +++ b/arch/powerpc/kernel/vdso/vgettimeofday.c @@ -18,23 +18,25 @@ int __c_kernel_clock_getres(clockid_t clock_id, struct __kernel_timespec *res, return __cvdso_clock_getres_data(vd, clock_id, res); } #else +#ifdef CONFIG_COMPAT_32BIT_TIME int __c_kernel_clock_gettime(clockid_t clock, struct old_timespec32 *ts, const struct vdso_time_data *vd) { return __cvdso_clock_gettime32_data(vd, clock, ts); } -int __c_kernel_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts, - const struct vdso_time_data *vd) -{ - return __cvdso_clock_gettime_data(vd, clock, ts); -} - int __c_kernel_clock_getres(clockid_t clock_id, struct old_timespec32 *res, const struct vdso_time_data *vd) { return __cvdso_clock_getres_time32_data(vd, clock_id, res); } +#endif /* CONFIG_COMPAT_32BIT_TIME */ + +int __c_kernel_clock_gettime64(clockid_t clock, struct __kernel_timespec *ts, + const struct vdso_time_data *vd) +{ + return __cvdso_clock_gettime_data(vd, clock, ts); +} int __c_kernel_clock_getres_time64(clockid_t clock_id, struct __kernel_timespec *res, const struct vdso_time_data *vd) @@ -43,6 +45,7 @@ int __c_kernel_clock_getres_time64(clockid_t clock_id, struct __kernel_timespec } #endif +#if defined(__powerpc64__) || defined(CONFIG_COMPAT_32BIT_TIME) int __c_kernel_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz, const struct vdso_time_data *vd) { @@ -53,3 +56,4 @@ __kernel_old_time_t __c_kernel_time(__kernel_old_time_t *time, const struct vdso { return __cvdso_time_data(vd, time); } +#endif |
