diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-09-08 07:59:12 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-09-08 07:59:12 -0700 |
| commit | 5acbae5f7eb3d5275120abfe698c394b7325dcec (patch) | |
| tree | cd81ba146ceb58fdb4e7d55cec800179e946a540 /arch/powerpc | |
| parent | 7daadf5131ed488037cc4540797e53c7f2c5d3ec (diff) | |
| parent | 45a5f7285f835adb3b74c9344c09a7bd2c4fb664 (diff) | |
| download | linux-master.tar.gz linux-master.zip | |
Pull powerpc fixes from Madhavan Srinivasan:
- Clear TIF_SYSCALL_RET before syscall error return
- Don't drop _TIF_RESTOREALL on syscall restart
- Do not restore KUAP in arch_exit_to_user_mode_prepare()
- pci-ioda: Fix the stale irq chip reference
- Use inclusive range checks in add_usable_mem() and excluded memory
- Fix irq_soft_mask corruption on replayed interrupt exit
- MAINTAINERS: powerpc: Add Ritesh and Shrikanth
- Misc fixes and cleanups
Thanks to Amit Machhiwal, Christophe Leroy (CS GROUP), Gautam Menghani,
Harsh Prateek Bora, Jiangshan Yi, Mukesh Kumar Chaurasiya (IBM), Ritesh
Harjani (IBM), Shivaprasad G Bhat, Shrikanth Hegde, Sourabh Jain,
Tasmiya Nalatwad, Thorsten Blum, and Venkat Rao Bagalkote.
* tag 'powerpc-7.3-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
MAINTAINERS: powerpc: Add Ritesh and Shrikanth
powerpc/ps3: Fix repository.c build failure
powerpc/entry: Fix irq_soft_mask corruption on replayed interrupt exit
powerpc/pseries/pci: Fix misleading VF limit error message
powerpc/kexec_file: Use inclusive range checks for excluded memory
powerpc/kexec: Simplify kdump_extra_elfcorehdr_size()
powerpc/kexec_file: Use inclusive range checks in add_usable_mem()
powerpc/rtas_pci: No hotplug on permanently removed device on pSeries
powerpc/eeh: Fix recursive locking on devices without EEH sensitive driver
powerpc: pci-ioda: Fix the stale irq chip reference
powerpc: Do not restore KUAP in arch_exit_to_user_mode_prepare()
powerpc: Don't drop _TIF_RESTOREALL on syscall restart
powerpc/entry: Clear TIF_SYSCALL_RET before syscall error return
Diffstat (limited to 'arch/powerpc')
| -rw-r--r-- | arch/powerpc/include/asm/entry-common.h | 12 | ||||
| -rw-r--r-- | arch/powerpc/kernel/eeh_driver.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/interrupt.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/kernel/rtas_pci.c | 8 | ||||
| -rw-r--r-- | arch/powerpc/kernel/syscall.c | 4 | ||||
| -rw-r--r-- | arch/powerpc/kexec/file_load_64.c | 10 | ||||
| -rw-r--r-- | arch/powerpc/platforms/powernv/pci-ioda.c | 6 | ||||
| -rw-r--r-- | arch/powerpc/platforms/ps3/repository.c | 5 | ||||
| -rw-r--r-- | arch/powerpc/platforms/pseries/pci.c | 13 |
9 files changed, 38 insertions, 24 deletions
diff --git a/arch/powerpc/include/asm/entry-common.h b/arch/powerpc/include/asm/entry-common.h index c5adb5006361..80b07750b531 100644 --- a/arch/powerpc/include/asm/entry-common.h +++ b/arch/powerpc/include/asm/entry-common.h @@ -270,7 +270,7 @@ static inline void arch_interrupt_exit_prepare(struct pt_regs *regs) } /* irqentry_exit expects to be called with interrupts disabled */ - local_irq_disable(); + hard_irq_disable(); } static inline void arch_interrupt_async_enter_prepare(struct pt_regs *regs) @@ -515,8 +515,14 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs, #ifdef CONFIG_PPC_TRANSACTIONAL_MEM local_paca->tm_scratch = regs->msr; #endif - /* Restore user access locks last */ - kuap_user_restore(regs); + /* + * Do not restore KUAP here. Generic entry might treat this as the last + * arch step before userspace but PowerPC still has kernel work after + * irqentry_exit()/syscall_exit_to_user_mode() i.e. in + * interrupt_exit_user_prepare() / syscall_exit_prepare() may enable + * IRQs and retry. Those functions restore KUAP immediately before rfi, + * which is where it should belong. + */ } #define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare 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/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/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/syscall.c b/arch/powerpc/kernel/syscall.c index 4916c205c4bb..fbefe1927b10 100644 --- a/arch/powerpc/kernel/syscall.c +++ b/arch/powerpc/kernel/syscall.c @@ -18,8 +18,10 @@ notrace long system_call_exception(struct pt_regs *regs, unsigned long r0) long ret; syscall_fn f; - if (unlikely(!syscall_enter_from_user_mode_randomize_stack(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); diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c index 6075b1c88511..bd80c5fb1b1f 100644 --- a/arch/powerpc/kexec/file_load_64.c +++ b/arch/powerpc/kexec/file_load_64.c @@ -57,7 +57,7 @@ int arch_check_excluded_range(struct kimage *image, unsigned long start, emem = image->arch.exclude_ranges; for (i = 0; i < emem->nr_ranges; i++) - if (start < emem->ranges[i].end && end > emem->ranges[i].start) + if (start <= emem->ranges[i].end && end >= emem->ranges[i].start) return 1; return 0; @@ -113,7 +113,7 @@ static int add_usable_mem(struct umem_info *um_info, u64 base, u64 end) loc_end = um_info->ranges[i].end; if (loc_base >= base && loc_end <= end) add = true; - else if (base < loc_end && end > loc_base) { + else if (base <= loc_end && end >= loc_base) { if (loc_base < base) loc_base = base; if (loc_end > end) @@ -377,16 +377,12 @@ static int load_backup_segment(struct kimage *image, struct kexec_buf *kbuf) static unsigned int kdump_extra_elfcorehdr_size(struct crash_mem *cmem) { #if defined(CONFIG_CRASH_HOTPLUG) && defined(CONFIG_MEMORY_HOTPLUG) - unsigned int extra_sz = 0; - if (CONFIG_CRASH_MAX_MEMORY_RANGES > (unsigned int)PN_XNUM) pr_warn("Number of Phdrs %u exceeds max\n", CONFIG_CRASH_MAX_MEMORY_RANGES); else if (cmem->nr_ranges >= CONFIG_CRASH_MAX_MEMORY_RANGES) pr_warn("Configured crash mem ranges may not be enough\n"); else - extra_sz = (CONFIG_CRASH_MAX_MEMORY_RANGES - cmem->nr_ranges) * sizeof(Elf64_Phdr); - - return extra_sz; + return (CONFIG_CRASH_MAX_MEMORY_RANGES - cmem->nr_ranges) * sizeof(Elf64_Phdr); #endif return 0; } diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 32ecbc46e74b..728a5610d167 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -1623,15 +1623,13 @@ int64_t pnv_opal_pci_msi_eoi(struct irq_data *d) return opal_pci_msi_eoi(phb->opal_id, d->parent_data->hwirq); } -static struct irq_chip pnv_pci_msi_irq_chip; - /* * Returns true iff chip is something that we could call * pnv_opal_pci_msi_eoi for. */ bool is_pnv_opal_msi(struct irq_chip *chip) { - return chip == &pnv_pci_msi_irq_chip; + return chip && chip->name && str_has_prefix(chip->name, "PNV-"); } EXPORT_SYMBOL_GPL(is_pnv_opal_msi); @@ -1728,7 +1726,7 @@ static const struct msi_parent_ops pnv_msi_parent_ops = { .chip_flags = MSI_CHIP_FLAG_SET_EOI, .bus_select_token = DOMAIN_BUS_NEXUS, .bus_select_mask = MATCH_PCI_MSI, - .prefix = "PNV-", + .prefix = "PNV-", /* Note: is_pnv_opal_msi() uses this */ .init_dev_msi_info = pnv_init_dev_msi_info, }; diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c index b8c030eab138..0cc755ac3e7f 100644 --- a/arch/powerpc/platforms/ps3/repository.c +++ b/arch/powerpc/platforms/ps3/repository.c @@ -6,6 +6,8 @@ * Copyright 2006 Sony Corp. */ +#include <linux/minmax.h> + #include <asm/lv1call.h> #include "platform.h" @@ -74,8 +76,9 @@ static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4, static u64 make_first_field(const char *text, u64 index) { u64 n = 0; + size_t len = min(strlen(text), sizeof(n)); - memcpy((char *)&n, text, strnlen(text, sizeof(n))); + memcpy(&n, text, len); return PS3_VENDOR_ID_NONE + (n >> 32) + index; } diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c index d11a64a086c1..6fc13f4a79a3 100644 --- a/arch/powerpc/platforms/pseries/pci.c +++ b/arch/powerpc/platforms/pseries/pci.c @@ -132,11 +132,14 @@ static int pseries_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs) /* First integer stores max config */ max_config_vfs = of_read_number(&max_vfs[0], 1); - if (max_config_vfs < num_vfs || num_vfs > MAX_VFS_FOR_MAP_PE) { - dev_err(&pdev->dev, - "Num VFs %x > %x Configurable VFs\n", - num_vfs, (num_vfs > MAX_VFS_FOR_MAP_PE) ? - MAX_VFS_FOR_MAP_PE : max_config_vfs); + if (max_config_vfs < num_vfs) { + dev_err(&pdev->dev, "Num VFs %x > %x Configurable VFs\n", + num_vfs, max_config_vfs); + return -EINVAL; + } + if (num_vfs > MAX_VFS_FOR_MAP_PE) { + dev_err(&pdev->dev, "Num VFs %x > %x PE mapping limit\n", + num_vfs, MAX_VFS_FOR_MAP_PE); return -EINVAL; } |
