[PATCH] tpm: Fix kexec crash due to access to ops NULL pointer (powerpc)
Fix the following crash on kexec by checking chip->ops for a NULL pointer in tpm_chip_start() and returning an error code if this is the case. BUG: Kernel NULL pointer dereference on read at 0x0060 Faulting instruction address: 0xc099a06c Oops: Kernel access of bad area, sig: 11 [#1] ... NIP [c099a06c] tpm_chip_start+0x2c/0x140 LR [c099a808] tpm_chip_unregister+0x108/0x170 Call Trace: [c000188bfa00] [c2b03930] fw_devlink_strict+0x0/0x8 (unreliable) [c000188bfa30] [c099a808] tpm_chip_unregister+0x108/0x170 [c000188bfa70] [c09a3874] tpm_ibmvtpm_remove+0x34/0x130 [c000188bfae0] [c0110dbc] vio_bus_remove+0x5c/0xb0 [c000188bfb20] [c09bc154] device_shutdown+0x1d4/0x3a8 [c000188bfbc0] [c0196e14] kernel_restart_prepare+0x54/0x70 The referenced patch below introduced a function to shut down the VIO bus. The bus shutdown now calls tpm_del_char_device (via tpm_chip_unregister) after a call to tpm_class_shutdown, which already set chip->ops to NULL. The crash occurrs when tpm_del_char_device calls tpm_chip_start with the chip->ops NULL pointer. Fixes: 39d0099f9439 ("powerpc/pseries: Add shutdown() to vio_driver and vio_bus") Signed-off-by: Stefan Berger --- drivers/char/tpm/tpm-chip.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index ddaeceb7e109..cca1bde296ee 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -101,6 +101,9 @@ int tpm_chip_start(struct tpm_chip *chip) { int ret; + if (!chip->ops) + return -EINVAL; + tpm_clk_enable(chip); if (chip->locality == -1) { -- 2.31.1
[PATCH v2 2/2] powerpc/module_64: Use patch_memory() to apply relocations to loaded modules
Livepatching a loaded module involves applying relocations through apply_relocate_add(), which attempts to write to read-only memory when CONFIG_STRICT_MODULE_RWX=y. Work around this by performing these writes through the text poke area by using patch_memory(). Similar to x86 and s390 implementations, apply_relocate_add() now chooses to use patch_memory() or memcpy() depending on if the module is loaded or not. Without STRICT_KERNEL_RWX, patch_memory() is just memcpy(), so there should be no performance impact. While many relocation types may not be applied in a livepatch context, comprehensively handling them prevents any issues in future, with no performance penalty as the text poke area is only used when necessary. create_stub() and create_ftrace_stub() are modified to first write to the stack so that the ppc64_stub_entry struct only takes one write() to modify, saving several map/unmap/flush operations when use of patch_memory() is necessary. This patch also contains some trivial whitespace fixes. Fixes: c35717c71e98 ("powerpc: Set ARCH_HAS_STRICT_MODULE_RWX") Reported-by: Joe Lawrence Signed-off-by: Russell Currey --- v2: No changes. Some discussion here:https://github.com/linuxppc/issues/issues/375 for-stable version using patch_instruction(): https://lore.kernel.org/linuxppc-dev/20211123081520.18843-1-rus...@russell.cc/ arch/powerpc/kernel/module_64.c | 157 +--- 1 file changed, 104 insertions(+), 53 deletions(-) diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 6baa676e7cb6..2a146750fa6f 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -350,11 +350,11 @@ static u32 stub_insns[] = { */ static inline int create_ftrace_stub(struct ppc64_stub_entry *entry, unsigned long addr, - struct module *me) + struct module *me, + void *(*write)(void *, const void *, size_t)) { long reladdr; - - memcpy(entry->jump, stub_insns, sizeof(stub_insns)); + struct ppc64_stub_entry tmp_entry; /* Stub uses address relative to kernel toc (from the paca) */ reladdr = addr - kernel_toc_addr(); @@ -364,12 +364,20 @@ static inline int create_ftrace_stub(struct ppc64_stub_entry *entry, return 0; } - entry->jump[1] |= PPC_HA(reladdr); - entry->jump[2] |= PPC_LO(reladdr); + /* +* In case @entry is write-protected, make our changes on the stack +* so we can update the whole struct in one write(). +*/ + memcpy(_entry, entry, sizeof(struct ppc64_stub_entry)); + memcpy(_entry.jump, stub_insns, sizeof(stub_insns)); + tmp_entry.jump[1] |= PPC_HA(reladdr); + tmp_entry.jump[2] |= PPC_LO(reladdr); /* Eventhough we don't use funcdata in the stub, it's needed elsewhere. */ - entry->funcdata = func_desc(addr); - entry->magic = STUB_MAGIC; + tmp_entry.funcdata = func_desc(addr); + tmp_entry.magic = STUB_MAGIC; + + write(entry, _entry, sizeof(struct ppc64_stub_entry)); return 1; } @@ -392,7 +400,8 @@ static bool is_mprofile_ftrace_call(const char *name) #else static inline int create_ftrace_stub(struct ppc64_stub_entry *entry, unsigned long addr, - struct module *me) + struct module *me, + void *(*write)(void *, const void *, size_t)) { return 0; } @@ -419,14 +428,14 @@ static inline int create_stub(const Elf64_Shdr *sechdrs, struct ppc64_stub_entry *entry, unsigned long addr, struct module *me, - const char *name) + const char *name, + void *(*write)(void *, const void *, size_t)) { long reladdr; + struct ppc64_stub_entry tmp_entry; if (is_mprofile_ftrace_call(name)) - return create_ftrace_stub(entry, addr, me); - - memcpy(entry->jump, ppc64_stub_insns, sizeof(ppc64_stub_insns)); + return create_ftrace_stub(entry, addr, me, write); /* Stub uses address relative to r2. */ reladdr = (unsigned long)entry - my_r2(sechdrs, me); @@ -437,10 +446,19 @@ static inline int create_stub(const Elf64_Shdr *sechdrs, } pr_debug("Stub %p get data from reladdr %li\n", entry, reladdr); - entry->jump[0] |= PPC_HA(reladdr); - entry->jump[1] |= PPC_LO(reladdr); - entry->funcdata = func_desc(addr); - entry->magic = STUB_MAGIC; + /* +* In case @entry is write-protected, make our changes on the stack +* so we can update the whole struct in one
[PATCH v2 1/2] powerpc/code-patching: add patch_memory() for writing RO text
powerpc allocates a text poke area of one page that is used by patch_instruction() to modify read-only text when STRICT_KERNEL_RWX is enabled. patch_instruction() is only designed for instructions, so writing data using the text poke area can only happen 4 bytes at a time - each with a page map/unmap, pte flush and syncs. This patch introduces patch_memory(), implementing the same interface as memcpy(), similar to x86's text_poke() and s390's s390_kernel_write(). patch_memory() only needs to map the text poke area once, unless the write would cross a page boundary. Signed-off-by: Russell Currey --- v2: Use min_t() instead of min(), fixing the 32-bit build as reported by snowpatch. Some discussion here: https://github.com/linuxppc/issues/issues/375 arch/powerpc/include/asm/code-patching.h | 1 + arch/powerpc/lib/code-patching.c | 74 2 files changed, 75 insertions(+) diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h index 4ba834599c4d..604211d8380c 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h @@ -31,6 +31,7 @@ int create_cond_branch(struct ppc_inst *instr, const u32 *addr, int patch_branch(u32 *addr, unsigned long target, int flags); int patch_instruction(u32 *addr, struct ppc_inst instr); int raw_patch_instruction(u32 *addr, struct ppc_inst instr); +void *patch_memory(void *dest, const void *src, size_t size); static inline unsigned long patch_site_addr(s32 *site) { diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index c5ed98823835..330602aa59f1 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -17,6 +17,7 @@ #include #include #include +#include static int __patch_instruction(u32 *exec_addr, struct ppc_inst instr, u32 *patch_addr) { @@ -178,6 +179,74 @@ static int do_patch_instruction(u32 *addr, struct ppc_inst instr) return err; } + +static int do_patch_memory(void *dest, const void *src, size_t size, unsigned long poke_addr) +{ + unsigned long patch_addr = poke_addr + offset_in_page(dest); + + if (map_patch_area(dest, poke_addr)) { + pr_warn("failed to map %lx\n", poke_addr); + return -1; + } + + memcpy((u8 *)patch_addr, src, size); + + flush_icache_range(patch_addr, size); + + if (unmap_patch_area(poke_addr)) { + pr_warn("failed to unmap %lx\n", poke_addr); + return -1; + } + + return 0; +} + +/** + * patch_memory - write data using the text poke area + * + * @dest: destination address + * @src: source address + * @size: size in bytes + * + * like memcpy(), but using the text poke area. No atomicity guarantees. + * Do not use for instructions, use patch_instruction() instead. + * Handles crossing page boundaries, though you shouldn't need to. + * + * Return value: + * @dest + **/ +void *patch_memory(void *dest, const void *src, size_t size) +{ + size_t bytes_written, write_size; + unsigned long text_poke_addr; + unsigned long flags; + + // If the poke area isn't set up, it's early boot and we can just memcpy. + if (!this_cpu_read(text_poke_area)) + return memcpy(dest, src, size); + + local_irq_save(flags); + text_poke_addr = (unsigned long)__this_cpu_read(text_poke_area)->addr; + + for (bytes_written = 0; +bytes_written < size; +bytes_written += write_size) { + // Write as much as possible without crossing a page boundary. + write_size = min_t(size_t, + size - bytes_written, + PAGE_SIZE - offset_in_page(dest + bytes_written)); + + if (do_patch_memory(dest + bytes_written, + src + bytes_written, + write_size, + text_poke_addr)) + break; + } + + local_irq_restore(flags); + + return dest; +} #else /* !CONFIG_STRICT_KERNEL_RWX */ static int do_patch_instruction(u32 *addr, struct ppc_inst instr) @@ -185,6 +254,11 @@ static int do_patch_instruction(u32 *addr, struct ppc_inst instr) return raw_patch_instruction(addr, instr); } +void *patch_memory(void *dest, const void *src, size_t size) +{ + return memcpy(dest, src, size); +} + #endif /* CONFIG_STRICT_KERNEL_RWX */ int patch_instruction(u32 *addr, struct ppc_inst instr) -- 2.34.1
Re: [PATCH v2 0/2] kdump: simplify code
Le 11/12/2021 à 18:53, David Laight a écrit : > From: Tiezhu Yang >> Sent: 11 December 2021 03:33 >> >> v2: >>-- add copy_to_user_or_kernel() in lib/usercopy.c >>-- define userbuf as bool type > > Instead of having a flag to indicate whether the buffer is user or kernel, > would it be better to have two separate buffer pointers. > One for a user space buffer, the other for a kernel space buffer. > Exactly one of the buffers should always be NULL. > > That way the flag is never incorrectly set. > It's a very good idea. I was worried about the casts forcing the __user property away and back. With that approach we will preserve the __user tags on user buffers and enable sparse checking. The only little drawback I see is that apparently GCC doesn't consider the NULL value as a constant and therefore doesn't perform constant folding on pointers. Not sure if this is a problem here. Christophe
RE: [PATCH v2 0/2] kdump: simplify code
From: Tiezhu Yang > Sent: 11 December 2021 03:33 > > v2: > -- add copy_to_user_or_kernel() in lib/usercopy.c > -- define userbuf as bool type Instead of having a flag to indicate whether the buffer is user or kernel, would it be better to have two separate buffer pointers. One for a user space buffer, the other for a kernel space buffer. Exactly one of the buffers should always be NULL. That way the flag is never incorrectly set. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
Re: [PATCH] PCI/AER: potential dereference of null pointer
[+cc Rajat, author of aer_stats: db89ccbe52c7 ("PCI/AER: Define aer_stats structure for AER capable devices" 81aa5206f9a7 ("PCI/AER: Add sysfs attributes to provide AER stats and breakdown"] On Thu, Dec 09, 2021 at 05:45:56PM +0800, Jiasheng Jiang wrote: > he return value of kzalloc() needs to be checked. > To avoid use of null pointer in case of the failure of alloc. > > Fixes: db89ccbe52c7 ("PCI/AER: Define aer_stats structure for AER capable > devices") > Signed-off-by: Jiasheng Jiang > --- > drivers/pci/pcie/aer.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c > index ec943cee5ecc..d04303edf468 100644 > --- a/drivers/pci/pcie/aer.c > +++ b/drivers/pci/pcie/aer.c > @@ -376,6 +376,8 @@ void pci_aer_init(struct pci_dev *dev) > return; > > dev->aer_stats = kzalloc(sizeof(struct aer_stats), GFP_KERNEL); > + if (!dev->aer_stats) > + return; Did you actually trip over a null pointer dereference, and if so, where was it? I think the intent here was that aer_stats is a non-essential feature, and if we can't allocate space to keep the statistics, we can still use the device without the stats. I *think* all the users of dev->aer_stats check for NULL before dereferencing it, but if you found a case that doesn't do that, we should definitely fix it. In a few cases (aer_stats_dev_attr, aer_stats_rootport_attr), the check isn't obvious -- it happens in aer_stats_attrs_are_visible(). If aer_stats_attrs_are_visible() finds that aer_stats is NULL, those sysfs attributes should not be visible, and the corresponding *_show() functions should never be called. > /* >* We save/restore PCI_ERR_UNCOR_MASK, PCI_ERR_UNCOR_SEVER, > -- > 2.25.1 >
Re: [patch V3 12/35] soc: ti: ti_sci_inta_msi: Allocate MSI device data on first use
On Fri, Dec 10, 2021 at 11:19 PM Thomas Gleixner wrote: > > From: Thomas Gleixner > > Allocate the MSI device data on first invocation of the allocation function. > > Signed-off-by: Thomas Gleixner > Reviewed-by: Greg Kroah-Hartman > Reviewed-by: Jason Gunthorpe > Cc: Nishanth Menon > Cc: Tero Kristo > Cc: Santosh Shilimkar > Cc: linux-arm-ker...@lists.infradead.org Acked-by: Arnd Bergmann
Re: [patch V3 34/35] soc: ti: ti_sci_inta_msi: Get rid of ti_sci_inta_msi_get_virq()
On Fri, Dec 10, 2021 at 11:19 PM Thomas Gleixner wrote: > > From: Thomas Gleixner > > Just use the core function msi_get_virq(). > > Signed-off-by: Thomas Gleixner > Reviewed-by: Greg Kroah-Hartman > Reviewed-by: Jason Gunthorpe > Cc: Peter Ujfalusi > Cc: Vinod Koul > Cc: dmaeng...@vger.kernel.org Acked-by: Arnd Bergmann
Re: [patch V3 07/35] device: Move MSI related data into a struct
On Fri, Dec 10, 2021 at 11:18 PM Thomas Gleixner wrote: > > From: Thomas Gleixner > > The only unconditional part of MSI data in struct device is the irqdomain > pointer. Everything else can be allocated on demand. Create a data > structure and move the irqdomain pointer into it. The other MSI specific > parts are going to be removed from struct device in later steps. > > Signed-off-by: Thomas Gleixner > Reviewed-by: Greg Kroah-Hartman > Reviewed-by: Jason Gunthorpe Acked-by: Arnd Bergmann
Re: [patch V3 05/35] powerpc/cell/axon_msi: Use PCI device property
On Fri, Dec 10, 2021 at 11:18 PM Thomas Gleixner wrote: > > From: Thomas Gleixner > > instead of fiddling with MSI descriptors. > > Signed-off-by: Thomas Gleixner > Cc: Arnd Bergmann > Cc: Michael Ellerman > Cc: Benjamin Herrenschmidt > Cc: linuxppc-dev@lists.ozlabs.org > --- Acked-by: Arnd Bergmann
[PATCH 2/2] powerpc/module_64: Use patch_memory() to apply relocations to loaded modules
Livepatching a loaded module involves applying relocations through apply_relocate_add(), which attempts to write to read-only memory when CONFIG_STRICT_MODULE_RWX=y. Work around this by performing these writes through the text poke area by using patch_memory(). Similar to x86 and s390 implementations, apply_relocate_add() now chooses to use patch_memory() or memcpy() depending on if the module is loaded or not. Without STRICT_KERNEL_RWX, patch_memory() is just memcpy(), so there should be no performance impact. While many relocation types may not be applied in a livepatch context, comprehensively handling them prevents any issues in future, with no performance penalty as the text poke area is only used when necessary. create_stub() and create_ftrace_stub() are modified to first write to the stack so that the ppc64_stub_entry struct only takes one write() to modify, saving several map/unmap/flush operations when use of patch_memory() is necessary. This patch also contains some trivial whitespace fixes. Fixes: c35717c71e98 ("powerpc: Set ARCH_HAS_STRICT_MODULE_RWX") Reported-by: Joe Lawrence Signed-off-by: Russell Currey --- Some discussion here:https://github.com/linuxppc/issues/issues/375 for-stable version using patch_instruction(): https://lore.kernel.org/linuxppc-dev/20211123081520.18843-1-rus...@russell.cc/ arch/powerpc/kernel/module_64.c | 157 +--- 1 file changed, 104 insertions(+), 53 deletions(-) diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 6baa676e7cb6..2a146750fa6f 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -350,11 +350,11 @@ static u32 stub_insns[] = { */ static inline int create_ftrace_stub(struct ppc64_stub_entry *entry, unsigned long addr, - struct module *me) + struct module *me, + void *(*write)(void *, const void *, size_t)) { long reladdr; - - memcpy(entry->jump, stub_insns, sizeof(stub_insns)); + struct ppc64_stub_entry tmp_entry; /* Stub uses address relative to kernel toc (from the paca) */ reladdr = addr - kernel_toc_addr(); @@ -364,12 +364,20 @@ static inline int create_ftrace_stub(struct ppc64_stub_entry *entry, return 0; } - entry->jump[1] |= PPC_HA(reladdr); - entry->jump[2] |= PPC_LO(reladdr); + /* +* In case @entry is write-protected, make our changes on the stack +* so we can update the whole struct in one write(). +*/ + memcpy(_entry, entry, sizeof(struct ppc64_stub_entry)); + memcpy(_entry.jump, stub_insns, sizeof(stub_insns)); + tmp_entry.jump[1] |= PPC_HA(reladdr); + tmp_entry.jump[2] |= PPC_LO(reladdr); /* Eventhough we don't use funcdata in the stub, it's needed elsewhere. */ - entry->funcdata = func_desc(addr); - entry->magic = STUB_MAGIC; + tmp_entry.funcdata = func_desc(addr); + tmp_entry.magic = STUB_MAGIC; + + write(entry, _entry, sizeof(struct ppc64_stub_entry)); return 1; } @@ -392,7 +400,8 @@ static bool is_mprofile_ftrace_call(const char *name) #else static inline int create_ftrace_stub(struct ppc64_stub_entry *entry, unsigned long addr, - struct module *me) + struct module *me, + void *(*write)(void *, const void *, size_t)) { return 0; } @@ -419,14 +428,14 @@ static inline int create_stub(const Elf64_Shdr *sechdrs, struct ppc64_stub_entry *entry, unsigned long addr, struct module *me, - const char *name) + const char *name, + void *(*write)(void *, const void *, size_t)) { long reladdr; + struct ppc64_stub_entry tmp_entry; if (is_mprofile_ftrace_call(name)) - return create_ftrace_stub(entry, addr, me); - - memcpy(entry->jump, ppc64_stub_insns, sizeof(ppc64_stub_insns)); + return create_ftrace_stub(entry, addr, me, write); /* Stub uses address relative to r2. */ reladdr = (unsigned long)entry - my_r2(sechdrs, me); @@ -437,10 +446,19 @@ static inline int create_stub(const Elf64_Shdr *sechdrs, } pr_debug("Stub %p get data from reladdr %li\n", entry, reladdr); - entry->jump[0] |= PPC_HA(reladdr); - entry->jump[1] |= PPC_LO(reladdr); - entry->funcdata = func_desc(addr); - entry->magic = STUB_MAGIC; + /* +* In case @entry is write-protected, make our changes on the stack +* so we can update the whole struct in one write(). +*/ +
[PATCH 1/2] powerpc/code-patching: add patch_memory() for writing RO text
powerpc allocates a text poke area of one page that is used by patch_instruction() to modify read-only text when STRICT_KERNEL_RWX is enabled. patch_instruction() is only designed for instructions, so writing data using the text poke area can only happen 4 bytes at a time - each with a page map/unmap, pte flush and syncs. This patch introduces patch_memory(), implementing the same interface as memcpy(), similar to x86's text_poke() and s390's s390_kernel_write(). patch_memory() only needs to map the text poke area once, unless the write would cross a page boundary. Signed-off-by: Russell Currey --- Sorry I took so long to post this. Some discussion here: https://github.com/linuxppc/issues/issues/375 arch/powerpc/include/asm/code-patching.h | 1 + arch/powerpc/lib/code-patching.c | 73 2 files changed, 74 insertions(+) diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h index 4ba834599c4d..604211d8380c 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h @@ -31,6 +31,7 @@ int create_cond_branch(struct ppc_inst *instr, const u32 *addr, int patch_branch(u32 *addr, unsigned long target, int flags); int patch_instruction(u32 *addr, struct ppc_inst instr); int raw_patch_instruction(u32 *addr, struct ppc_inst instr); +void *patch_memory(void *dest, const void *src, size_t size); static inline unsigned long patch_site_addr(s32 *site) { diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index c5ed98823835..3a566d756ccc 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -17,6 +17,7 @@ #include #include #include +#include static int __patch_instruction(u32 *exec_addr, struct ppc_inst instr, u32 *patch_addr) { @@ -178,6 +179,73 @@ static int do_patch_instruction(u32 *addr, struct ppc_inst instr) return err; } + +static int do_patch_memory(void *dest, const void *src, size_t size, unsigned long poke_addr) +{ + unsigned long patch_addr = poke_addr + offset_in_page(dest); + + if (map_patch_area(dest, poke_addr)) { + pr_warn("failed to map %lx\n", poke_addr); + return -1; + } + + memcpy((u8 *)patch_addr, src, size); + + flush_icache_range(patch_addr, size); + + if (unmap_patch_area(poke_addr)) { + pr_warn("failed to unmap %lx\n", poke_addr); + return -1; + } + + return 0; +} + +/** + * patch_memory - write data using the text poke area + * + * @dest: destination address + * @src: source address + * @size: size in bytes + * + * like memcpy(), but using the text poke area. No atomicity guarantees. + * Do not use for instructions, use patch_instruction() instead. + * Handles crossing page boundaries, though you shouldn't need to. + * + * Return value: + * @dest + **/ +void *patch_memory(void *dest, const void *src, size_t size) +{ + size_t bytes_written, write_size; + unsigned long text_poke_addr; + unsigned long flags; + + // If the poke area isn't set up, it's early boot and we can just memcpy. + if (!this_cpu_read(text_poke_area)) + return memcpy(dest, src, size); + + local_irq_save(flags); + text_poke_addr = (unsigned long)__this_cpu_read(text_poke_area)->addr; + + for (bytes_written = 0; +bytes_written < size; +bytes_written += write_size) { + // Write as much as possible without crossing a page boundary. + write_size = min(size - bytes_written, +PAGE_SIZE - offset_in_page(dest + bytes_written)); + + if (do_patch_memory(dest + bytes_written, + src + bytes_written, + write_size, + text_poke_addr)) + break; + } + + local_irq_restore(flags); + + return dest; +} #else /* !CONFIG_STRICT_KERNEL_RWX */ static int do_patch_instruction(u32 *addr, struct ppc_inst instr) @@ -185,6 +253,11 @@ static int do_patch_instruction(u32 *addr, struct ppc_inst instr) return raw_patch_instruction(addr, instr); } +void *patch_memory(void *dest, const void *src, size_t size) +{ + return memcpy(dest, src, size); +} + #endif /* CONFIG_STRICT_KERNEL_RWX */ int patch_instruction(u32 *addr, struct ppc_inst instr) -- 2.34.1
Re: [patch V3 03/35] x86/apic/msi: Use PCI device MSI property
On Fri, Dec 10, 2021 at 11:18:47PM +0100, Thomas Gleixner wrote: > From: Thomas Gleixner > > instead of fiddling with MSI descriptors. > > Signed-off-by: Thomas Gleixner Reviewed-by: Greg Kroah-Hartman
[next-20211210] Build break powerpc/kvm: unknown member wait
next-20211210 ( commit ea922272cbe547) powerpc build fails due to following error: arch/powerpc/kvm/book3s_hv.c: In function 'kvmhv_run_single_vcpu': arch/powerpc/kvm/book3s_hv.c:4591:27: error: 'struct kvm_vcpu' has no member named 'wait' prepare_to_rcuwait(>wait); ^~ arch/powerpc/kvm/book3s_hv.c:4608:23: error: 'struct kvm_vcpu' has no member named 'wait' finish_rcuwait(>wait); ^~ commit 510958e997217: KVM: Force PPC to define its own rcuwait object introduced the error. Thanks -Sachin
Re: [PATCH v2 1/2] kdump: vmcore: remove copy_to() and add copy_to_user_or_kernel()
Le 11/12/2021 à 04:33, Tiezhu Yang a écrit : > In arch/*/kernel/crash_dump*.c, there exist many similar code > about copy_oldmem_page(), remove copy_to() in fs/proc/vmcore.c > and add copy_to_user_or_kernel() in lib/usercopy.c, then we can > use copy_to_user_or_kernel() to simplify the related code. It should be an inline function in uaccess.h, see below why. > > Signed-off-by: Tiezhu Yang > --- > fs/proc/vmcore.c| 28 +++- > include/linux/uaccess.h | 1 + > lib/usercopy.c | 15 +++ > 3 files changed, 23 insertions(+), 21 deletions(-) > > diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c > index 509f851..f67fd77 100644 > --- a/fs/proc/vmcore.c > +++ b/fs/proc/vmcore.c > @@ -238,22 +238,8 @@ copy_oldmem_page_encrypted(unsigned long pfn, char *buf, > size_t csize, > return copy_oldmem_page(pfn, buf, csize, offset, userbuf); > } > > -/* > - * Copy to either kernel or user space > - */ > -static int copy_to(void *target, void *src, size_t size, int userbuf) > -{ > - if (userbuf) { > - if (copy_to_user((char __user *) target, src, size)) > - return -EFAULT; > - } else { > - memcpy(target, src, size); > - } > - return 0; > -} > - > #ifdef CONFIG_PROC_VMCORE_DEVICE_DUMP > -static int vmcoredd_copy_dumps(void *dst, u64 start, size_t size, int > userbuf) > +static int vmcoredd_copy_dumps(void *dst, u64 start, size_t size, bool > userbuf) Changing int to bool in all the callers should be another patch. You can have copy_to_user_or_kernel() take a bool in the patch while still having all the callers using an int. > { > struct vmcoredd_node *dump; > u64 offset = 0; > @@ -266,7 +252,7 @@ static int vmcoredd_copy_dumps(void *dst, u64 start, > size_t size, int userbuf) > if (start < offset + dump->size) { > tsz = min(offset + (u64)dump->size - start, (u64)size); > buf = dump->buf + start - offset; > - if (copy_to(dst, buf, tsz, userbuf)) { > + if (copy_to_user_or_kernel(dst, buf, tsz, userbuf)) { > ret = -EFAULT; > goto out_unlock; > } > @@ -330,7 +316,7 @@ static int vmcoredd_mmap_dumps(struct vm_area_struct > *vma, unsigned long dst, >* returned otherwise number of bytes read are returned. >*/ > static ssize_t __read_vmcore(char *buffer, size_t buflen, loff_t *fpos, > - int userbuf) > + bool userbuf) > { > ssize_t acc = 0, tmp; > size_t tsz; > @@ -347,7 +333,7 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, > loff_t *fpos, > /* Read ELF core header */ > if (*fpos < elfcorebuf_sz) { > tsz = min(elfcorebuf_sz - (size_t)*fpos, buflen); > - if (copy_to(buffer, elfcorebuf + *fpos, tsz, userbuf)) > + if (copy_to_user_or_kernel(buffer, elfcorebuf + *fpos, tsz, > userbuf)) > return -EFAULT; > buflen -= tsz; > *fpos += tsz; > @@ -395,7 +381,7 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, > loff_t *fpos, > /* Read remaining elf notes */ > tsz = min(elfcorebuf_sz + elfnotes_sz - (size_t)*fpos, buflen); > kaddr = elfnotes_buf + *fpos - elfcorebuf_sz - vmcoredd_orig_sz; > - if (copy_to(buffer, kaddr, tsz, userbuf)) > + if (copy_to_user_or_kernel(buffer, kaddr, tsz, userbuf)) > return -EFAULT; > > buflen -= tsz; > @@ -435,7 +421,7 @@ static ssize_t __read_vmcore(char *buffer, size_t buflen, > loff_t *fpos, > static ssize_t read_vmcore(struct file *file, char __user *buffer, > size_t buflen, loff_t *fpos) > { > - return __read_vmcore((__force char *) buffer, buflen, fpos, 1); > + return __read_vmcore((__force char *) buffer, buflen, fpos, true); > } > > /* > @@ -461,7 +447,7 @@ static vm_fault_t mmap_vmcore_fault(struct vm_fault *vmf) > if (!PageUptodate(page)) { > offset = (loff_t) index << PAGE_SHIFT; > buf = __va((page_to_pfn(page) << PAGE_SHIFT)); > - rc = __read_vmcore(buf, PAGE_SIZE, , 0); > + rc = __read_vmcore(buf, PAGE_SIZE, , false); > if (rc < 0) { > unlock_page(page); > put_page(page); > diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h > index ac03940..a25e682e 100644 > --- a/include/linux/uaccess.h > +++ b/include/linux/uaccess.h > @@ -283,6 +283,7 @@ __copy_from_user_inatomic_nocache(void *to, const void > __user *from, > #endif /* ARCH_HAS_NOCACHE_UACCESS */ > > extern __must_check int check_zeroed_user(const void __user *from, size_t > size); > +extern __must_check int
[PATCH] soc: fsl: qe: fix typo in a comment
The double `is' in the comment in line 150 is repeated. Remove one of them from the comment. Signed-off-by: Jason Wang --- drivers/soc/fsl/qe/qe.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c index 4d38c80f8be8..b3c226eb5292 100644 --- a/drivers/soc/fsl/qe/qe.c +++ b/drivers/soc/fsl/qe/qe.c @@ -147,7 +147,7 @@ EXPORT_SYMBOL(qe_issue_cmd); * memory mapped space. * The BRG clock is the QE clock divided by 2. * It was set up long ago during the initial boot phase and is - * is given to us. + * given to us. * Baud rate clocks are zero-based in the driver code (as that maps * to port numbers). Documentation uses 1-based numbering. */ @@ -421,7 +421,7 @@ static void qe_upload_microcode(const void *base, for (i = 0; i < be32_to_cpu(ucode->count); i++) iowrite32be(be32_to_cpu(code[i]), _immr->iram.idata); - + /* Set I-RAM Ready Register */ iowrite32be(QE_IRAM_READY, _immr->iram.iready); } -- 2.34.1