* [PATCH v5 3/5] fork: support VMAP_STACK with KASAN_VMALLOC
From: Daniel Axtens @ 2019-08-30 0:38 UTC (permalink / raw)
To: kasan-dev, linux-mm, x86, aryabinin, glider, luto, linux-kernel,
mark.rutland, dvyukov, christophe.leroy
Cc: linuxppc-dev, gor, Daniel Axtens
In-Reply-To: <20190830003821.10737-1-dja@axtens.net>
Supporting VMAP_STACK with KASAN_VMALLOC is straightforward:
- clear the shadow region of vmapped stacks when swapping them in
- tweak Kconfig to allow VMAP_STACK to be turned on with KASAN
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
arch/Kconfig | 9 +++++----
kernel/fork.c | 4 ++++
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/arch/Kconfig b/arch/Kconfig
index 6728c5fa057e..e15f1486682a 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -843,16 +843,17 @@ config HAVE_ARCH_VMAP_STACK
config VMAP_STACK
default y
bool "Use a virtually-mapped stack"
- depends on HAVE_ARCH_VMAP_STACK && !KASAN
+ depends on HAVE_ARCH_VMAP_STACK
+ depends on !KASAN || KASAN_VMALLOC
---help---
Enable this if you want the use virtually-mapped kernel stacks
with guard pages. This causes kernel stack overflows to be
caught immediately rather than causing difficult-to-diagnose
corruption.
- This is presently incompatible with KASAN because KASAN expects
- the stack to map directly to the KASAN shadow map using a formula
- that is incorrect if the stack is in vmalloc space.
+ To use this with KASAN, the architecture must support backing
+ virtual mappings with real shadow memory, and KASAN_VMALLOC must
+ be enabled.
config ARCH_OPTIONAL_KERNEL_RWX
def_bool n
diff --git a/kernel/fork.c b/kernel/fork.c
index f601168f6b21..52279fd5e72d 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -94,6 +94,7 @@
#include <linux/livepatch.h>
#include <linux/thread_info.h>
#include <linux/stackleak.h>
+#include <linux/kasan.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -229,6 +230,9 @@ static unsigned long *alloc_thread_stack_node(struct task_struct *tsk, int node)
if (!s)
continue;
+ /* Clear the KASAN shadow of the stack. */
+ kasan_unpoison_shadow(s->addr, THREAD_SIZE);
+
/* Clear stale pointers from reused stack. */
memset(s->addr, 0, THREAD_SIZE);
--
2.20.1
^ permalink raw reply related
* [PATCH v5 4/5] x86/kasan: support KASAN_VMALLOC
From: Daniel Axtens @ 2019-08-30 0:38 UTC (permalink / raw)
To: kasan-dev, linux-mm, x86, aryabinin, glider, luto, linux-kernel,
mark.rutland, dvyukov, christophe.leroy
Cc: linuxppc-dev, gor, Daniel Axtens
In-Reply-To: <20190830003821.10737-1-dja@axtens.net>
In the case where KASAN directly allocates memory to back vmalloc
space, don't map the early shadow page over it.
We prepopulate pgds/p4ds for the range that would otherwise be empty.
This is required to get it synced to hardware on boot, allowing the
lower levels of the page tables to be filled dynamically.
Acked-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
v5: fix some checkpatch CHECK warnings. There are some that remain
around lines ending with '(': I have not changed these because
it's consistent with the rest of the file and it's not easy to
see how to fix it without creating an overlong line or lots of
temporary variables.
v2: move from faulting in shadow pgds to prepopulating
---
arch/x86/Kconfig | 1 +
arch/x86/mm/kasan_init_64.c | 60 +++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 2502f7f60c9c..300b4766ccfa 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -134,6 +134,7 @@ config X86
select HAVE_ARCH_JUMP_LABEL
select HAVE_ARCH_JUMP_LABEL_RELATIVE
select HAVE_ARCH_KASAN if X86_64
+ select HAVE_ARCH_KASAN_VMALLOC if X86_64
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS if MMU
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if MMU && COMPAT
diff --git a/arch/x86/mm/kasan_init_64.c b/arch/x86/mm/kasan_init_64.c
index 296da58f3013..8f00f462709e 100644
--- a/arch/x86/mm/kasan_init_64.c
+++ b/arch/x86/mm/kasan_init_64.c
@@ -245,6 +245,51 @@ static void __init kasan_map_early_shadow(pgd_t *pgd)
} while (pgd++, addr = next, addr != end);
}
+static void __init kasan_shallow_populate_p4ds(pgd_t *pgd,
+ unsigned long addr,
+ unsigned long end,
+ int nid)
+{
+ p4d_t *p4d;
+ unsigned long next;
+ void *p;
+
+ p4d = p4d_offset(pgd, addr);
+ do {
+ next = p4d_addr_end(addr, end);
+
+ if (p4d_none(*p4d)) {
+ p = early_alloc(PAGE_SIZE, nid, true);
+ p4d_populate(&init_mm, p4d, p);
+ }
+ } while (p4d++, addr = next, addr != end);
+}
+
+static void __init kasan_shallow_populate_pgds(void *start, void *end)
+{
+ unsigned long addr, next;
+ pgd_t *pgd;
+ void *p;
+ int nid = early_pfn_to_nid((unsigned long)start);
+
+ addr = (unsigned long)start;
+ pgd = pgd_offset_k(addr);
+ do {
+ next = pgd_addr_end(addr, (unsigned long)end);
+
+ if (pgd_none(*pgd)) {
+ p = early_alloc(PAGE_SIZE, nid, true);
+ pgd_populate(&init_mm, pgd, p);
+ }
+
+ /*
+ * we need to populate p4ds to be synced when running in
+ * four level mode - see sync_global_pgds_l4()
+ */
+ kasan_shallow_populate_p4ds(pgd, addr, next, nid);
+ } while (pgd++, addr = next, addr != (unsigned long)end);
+}
+
#ifdef CONFIG_KASAN_INLINE
static int kasan_die_handler(struct notifier_block *self,
unsigned long val,
@@ -352,9 +397,24 @@ void __init kasan_init(void)
shadow_cpu_entry_end = (void *)round_up(
(unsigned long)shadow_cpu_entry_end, PAGE_SIZE);
+ /*
+ * If we're in full vmalloc mode, don't back vmalloc space with early
+ * shadow pages. Instead, prepopulate pgds/p4ds so they are synced to
+ * the global table and we can populate the lower levels on demand.
+ */
+#ifdef CONFIG_KASAN_VMALLOC
+ kasan_shallow_populate_pgds(
+ kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM),
+ kasan_mem_to_shadow((void *)VMALLOC_END));
+
+ kasan_populate_early_shadow(
+ kasan_mem_to_shadow((void *)VMALLOC_END + 1),
+ shadow_cpu_entry_begin);
+#else
kasan_populate_early_shadow(
kasan_mem_to_shadow((void *)PAGE_OFFSET + MAXMEM),
shadow_cpu_entry_begin);
+#endif
kasan_populate_shadow((unsigned long)shadow_cpu_entry_begin,
(unsigned long)shadow_cpu_entry_end, 0);
--
2.20.1
^ permalink raw reply related
* [PATCH v5 5/5] kasan debug: track pages allocated for vmalloc shadow
From: Daniel Axtens @ 2019-08-30 0:38 UTC (permalink / raw)
To: kasan-dev, linux-mm, x86, aryabinin, glider, luto, linux-kernel,
mark.rutland, dvyukov, christophe.leroy
Cc: linuxppc-dev, gor, Daniel Axtens
In-Reply-To: <20190830003821.10737-1-dja@axtens.net>
Provide the current number of vmalloc shadow pages in
/sys/kernel/debug/kasan_vmalloc/shadow_pages.
Signed-off-by: Daniel Axtens <dja@axtens.net>
---
Merging this is probably overkill, but I leave it to the discretion
of the broader community.
On v4 (no dynamic freeing), I saw the following approximate figures
on my test VM:
- fresh boot: 720
- after test_vmalloc: ~14000
With v5 (lazy dynamic freeing):
- boot: ~490-500
- running modprobe test_vmalloc pushes the figures up to sometimes
as high as ~14000, but they drop down to ~560 after the test ends.
I'm not sure where the extra sixty pages are from, but running the
test repeately doesn't cause the number to keep growing, so I don't
think we're leaking.
- with vmap_stack, spawning tasks pushes the figure up to ~4200, then
some clearing kicks in and drops it down to previous levels again.
---
mm/kasan/common.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/mm/kasan/common.c b/mm/kasan/common.c
index c12a2e6ecff5..69f32f2857b0 100644
--- a/mm/kasan/common.c
+++ b/mm/kasan/common.c
@@ -35,6 +35,7 @@
#include <linux/vmalloc.h>
#include <linux/bug.h>
#include <linux/uaccess.h>
+#include <linux/debugfs.h>
#include "kasan.h"
#include "../slab.h"
@@ -748,6 +749,8 @@ core_initcall(kasan_memhotplug_init);
#endif
#ifdef CONFIG_KASAN_VMALLOC
+static u64 vmalloc_shadow_pages;
+
static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr,
void *unused)
{
@@ -774,6 +777,7 @@ static int kasan_populate_vmalloc_pte(pte_t *ptep, unsigned long addr,
if (likely(pte_none(*ptep))) {
set_pte_at(&init_mm, addr, ptep, pte);
page = 0;
+ vmalloc_shadow_pages++;
}
spin_unlock(&init_mm.page_table_lock);
if (page)
@@ -833,6 +837,7 @@ static int kasan_depopulate_vmalloc_pte(pte_t *ptep, unsigned long addr,
pte_clear(&init_mm, addr, ptep);
free_page(page);
+ vmalloc_shadow_pages--;
spin_unlock(&init_mm.page_table_lock);
return 0;
@@ -887,4 +892,25 @@ void kasan_release_vmalloc(unsigned long start, unsigned long end,
(unsigned long)(shadow_end - shadow_start),
kasan_depopulate_vmalloc_pte, NULL);
}
+
+static __init int kasan_init_vmalloc_debugfs(void)
+{
+ struct dentry *root, *count;
+
+ root = debugfs_create_dir("kasan_vmalloc", NULL);
+ if (IS_ERR(root)) {
+ if (PTR_ERR(root) == -ENODEV)
+ return 0;
+ return PTR_ERR(root);
+ }
+
+ count = debugfs_create_u64("shadow_pages", 0444, root,
+ &vmalloc_shadow_pages);
+
+ if (IS_ERR(count))
+ return PTR_ERR(root);
+
+ return 0;
+}
+late_initcall(kasan_init_vmalloc_debugfs);
#endif
--
2.20.1
^ permalink raw reply related
* [PATCH] powerpc/64s/exceptions: Use keyword params to shorten arg lists
From: Michael Ellerman @ 2019-08-30 1:14 UTC (permalink / raw)
To: linuxppc-dev; +Cc: npiggin
The argument lists for the INT_HANDLER macro are getting a bit
unwieldy. Use keyword parameters with default values to shorten them.
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/kernel/exceptions-64s.S | 120 +++++++++++++--------------
1 file changed, 60 insertions(+), 60 deletions(-)
This slots in after patch 22 of Nick's mega series.
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index a476bb2f80f3..10037981ff2a 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -619,7 +619,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
* - Fall through and continue executing in real, unrelocated mode.
* This is done if early=2.
*/
-.macro INT_HANDLER name, vec, ool, early, virt, hsrr, area, ri, dar, dsisr, bitmask, kvm
+.macro INT_HANDLER name, vec, ool=0, early=0, virt=0, hsrr=0, area=PACA_EXGEN, ri=1, dar=0, dsisr=0, bitmask=0, kvm=0
EXCEPTION_PROLOG_0 \area
.if \ool
.if !\virt
@@ -812,7 +812,7 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206)
#endif
- INT_HANDLER system_reset, 0x100, 0, 0, 0, EXC_STD, PACA_EXNMI, 0, 0, 0, 0, 1
+ INT_HANDLER system_reset, 0x100, area=PACA_EXNMI, ri=0, kvm=1
/*
* MSR_RI is not enabled, because PACA_EXNMI and nmi stack is
* being used, so a nested NMI exception would corrupt it.
@@ -842,7 +842,7 @@ TRAMP_REAL_BEGIN(system_reset_idle_wake)
*/
TRAMP_REAL_BEGIN(system_reset_fwnmi)
/* See comment at system_reset exception, don't turn on RI */
- INT_HANDLER system_reset, 0x100, 0, 0, 0, EXC_STD, PACA_EXNMI, 0, 0, 0, 0, 0
+ INT_HANDLER system_reset, 0x100, area=PACA_EXNMI, ri=0
#endif /* CONFIG_PPC_PSERIES */
@@ -905,7 +905,7 @@ EXC_COMMON_BEGIN(system_reset_common)
EXC_REAL_BEGIN(machine_check, 0x200, 0x100)
- INT_HANDLER machine_check, 0x200, 0, 1, 0, EXC_STD, PACA_EXMC, 0, 1, 1, 0, 0
+ INT_HANDLER machine_check, 0x200, early=1, area=PACA_EXMC, dar=1, dsisr=1
/*
* MSR_RI is not enabled, because PACA_EXMC is being used, so a
* nested machine check corrupts it. machine_check_common enables
@@ -917,7 +917,7 @@ EXC_VIRT_NONE(0x4200, 0x100)
#ifdef CONFIG_PPC_PSERIES
TRAMP_REAL_BEGIN(machine_check_fwnmi)
/* See comment at machine_check exception, don't turn on RI */
- INT_HANDLER machine_check, 0x200, 0, 1, 0, EXC_STD, PACA_EXMC, 0, 1, 1, 0, 0
+ INT_HANDLER machine_check, 0x200, early=1, area=PACA_EXMC, dar=1, dsisr=1
#endif
TRAMP_KVM_SKIP(PACA_EXMC, 0x200)
@@ -1068,7 +1068,7 @@ BEGIN_FTR_SECTION
END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
MACHINE_CHECK_HANDLER_WINDUP
/* See comment at machine_check exception, don't turn on RI */
- INT_HANDLER machine_check, 0x200, 0, 0, 0, EXC_STD, PACA_EXMC, 0, 1, 1, 0, 1
+ INT_HANDLER machine_check, 0x200, area=PACA_EXMC, ri=0, dar=1, dsisr=1, kvm=1
EXC_COMMON_BEGIN(machine_check_common)
/*
@@ -1154,10 +1154,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE)
EXC_REAL_BEGIN(data_access, 0x300, 0x80)
- INT_HANDLER data_access, 0x300, 1, 0, 0, EXC_STD, PACA_EXGEN, 1, 1, 1, 0, 1
+ INT_HANDLER data_access, 0x300, ool=1, dar=1, dsisr=1, kvm=1
EXC_REAL_END(data_access, 0x300, 0x80)
EXC_VIRT_BEGIN(data_access, 0x4300, 0x80)
- INT_HANDLER data_access, 0x300, 0, 0, 1, EXC_STD, PACA_EXGEN, 1, 1, 1, 0, 0
+ INT_HANDLER data_access, 0x300, virt=1, dar=1, dsisr=1
EXC_VIRT_END(data_access, 0x4300, 0x80)
TRAMP_KVM_SKIP(PACA_EXGEN, 0x300)
@@ -1185,10 +1185,10 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
EXC_REAL_BEGIN(data_access_slb, 0x380, 0x80)
- INT_HANDLER data_access_slb, 0x380, 1, 0, 0, 0, PACA_EXSLB, 1, 1, 0, 0, 1
+ INT_HANDLER data_access_slb, 0x380, ool=1, area=PACA_EXSLB, dar=1, kvm=1
EXC_REAL_END(data_access_slb, 0x380, 0x80)
EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80)
- INT_HANDLER data_access_slb, 0x380, 0, 0, 1, 0, PACA_EXSLB, 1, 1, 0, 0, 0
+ INT_HANDLER data_access_slb, 0x380, virt=1, area=PACA_EXSLB, dar=1
EXC_VIRT_END(data_access_slb, 0x4380, 0x80)
TRAMP_KVM_SKIP(PACA_EXSLB, 0x380)
@@ -1220,10 +1220,10 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
EXC_REAL_BEGIN(instruction_access, 0x400, 0x80)
- INT_HANDLER instruction_access, 0x400, 0, 0, 0, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER instruction_access, 0x400, kvm=1
EXC_REAL_END(instruction_access, 0x400, 0x80)
EXC_VIRT_BEGIN(instruction_access, 0x4400, 0x80)
- INT_HANDLER instruction_access, 0x400, 0, 0, 1, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 0
+ INT_HANDLER instruction_access, 0x400, virt=1
EXC_VIRT_END(instruction_access, 0x4400, 0x80)
TRAMP_KVM(PACA_EXGEN, 0x400)
@@ -1245,10 +1245,10 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
EXC_REAL_BEGIN(instruction_access_slb, 0x480, 0x80)
- INT_HANDLER instruction_access_slb, 0x480, 0, 0, 0, EXC_STD, PACA_EXSLB, 1, 0, 0, 0, 1
+ INT_HANDLER instruction_access_slb, 0x480, area=PACA_EXSLB, kvm=1
EXC_REAL_END(instruction_access_slb, 0x480, 0x80)
EXC_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x80)
- INT_HANDLER instruction_access_slb, 0x480, 0, 0, 1, EXC_STD, PACA_EXSLB, 1, 0, 0, 0, 0
+ INT_HANDLER instruction_access_slb, 0x480, virt=1, area=PACA_EXSLB
EXC_VIRT_END(instruction_access_slb, 0x4480, 0x80)
TRAMP_KVM(PACA_EXSLB, 0x480)
@@ -1277,10 +1277,10 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
b ret_from_except
EXC_REAL_BEGIN(hardware_interrupt, 0x500, 0x100)
- INT_HANDLER hardware_interrupt, 0x500, 0, 0, 0, EXC_HV_OR_STD, PACA_EXGEN, 1, 0, 0, IRQS_DISABLED, 1
+ INT_HANDLER hardware_interrupt, 0x500, hsrr=EXC_HV_OR_STD, bitmask=IRQS_DISABLED, kvm=1
EXC_REAL_END(hardware_interrupt, 0x500, 0x100)
EXC_VIRT_BEGIN(hardware_interrupt, 0x4500, 0x100)
- INT_HANDLER hardware_interrupt, 0x500, 0, 0, 1, EXC_HV_OR_STD, PACA_EXGEN, 1, 0, 0, IRQS_DISABLED, 1
+ INT_HANDLER hardware_interrupt, 0x500, virt=1, hsrr=EXC_HV_OR_STD, bitmask=IRQS_DISABLED, kvm=1
EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100)
TRAMP_KVM(PACA_EXGEN, 0x500)
@@ -1289,10 +1289,10 @@ EXC_COMMON_ASYNC(hardware_interrupt_common, 0x500, do_IRQ)
EXC_REAL_BEGIN(alignment, 0x600, 0x100)
- INT_HANDLER alignment, 0x600, 0, 0, 0, EXC_STD, PACA_EXGEN, 1, 1, 1, 0, 1
+ INT_HANDLER alignment, 0x600, dar=1, dsisr=1, kvm=1
EXC_REAL_END(alignment, 0x600, 0x100)
EXC_VIRT_BEGIN(alignment, 0x4600, 0x100)
- INT_HANDLER alignment, 0x600, 0, 0, 1, EXC_STD, PACA_EXGEN, 1, 1, 1, 0, 0
+ INT_HANDLER alignment, 0x600, virt=1, dar=1, dsisr=1
EXC_VIRT_END(alignment, 0x4600, 0x100)
TRAMP_KVM(PACA_EXGEN, 0x600)
@@ -1310,10 +1310,10 @@ EXC_COMMON_BEGIN(alignment_common)
EXC_REAL_BEGIN(program_check, 0x700, 0x100)
- INT_HANDLER program_check, 0x700, 0, 0, 0, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER program_check, 0x700, kvm=1
EXC_REAL_END(program_check, 0x700, 0x100)
EXC_VIRT_BEGIN(program_check, 0x4700, 0x100)
- INT_HANDLER program_check, 0x700, 0, 0, 1, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 0
+ INT_HANDLER program_check, 0x700, virt=1
EXC_VIRT_END(program_check, 0x4700, 0x100)
TRAMP_KVM(PACA_EXGEN, 0x700)
EXC_COMMON_BEGIN(program_check_common)
@@ -1352,10 +1352,10 @@ EXC_COMMON_BEGIN(program_check_common)
EXC_REAL_BEGIN(fp_unavailable, 0x800, 0x100)
- INT_HANDLER fp_unavailable, 0x800, 0, 0, 0, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER fp_unavailable, 0x800, kvm=1
EXC_REAL_END(fp_unavailable, 0x800, 0x100)
EXC_VIRT_BEGIN(fp_unavailable, 0x4800, 0x100)
- INT_HANDLER fp_unavailable, 0x800, 0, 0, 1, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 0
+ INT_HANDLER fp_unavailable, 0x800, virt=1
EXC_VIRT_END(fp_unavailable, 0x4800, 0x100)
TRAMP_KVM(PACA_EXGEN, 0x800)
EXC_COMMON_BEGIN(fp_unavailable_common)
@@ -1390,30 +1390,30 @@ END_FTR_SECTION_IFSET(CPU_FTR_TM)
EXC_REAL_BEGIN(decrementer, 0x900, 0x80)
- INT_HANDLER decrementer, 0x900, 1, 0, 0, EXC_STD, PACA_EXGEN, 1, 0, 0, IRQS_DISABLED, 1
+ INT_HANDLER decrementer, 0x900, ool=1, bitmask=IRQS_DISABLED, kvm=1
EXC_REAL_END(decrementer, 0x900, 0x80)
EXC_VIRT_BEGIN(decrementer, 0x4900, 0x80)
- INT_HANDLER decrementer, 0x900, 0, 0, 1, EXC_STD, PACA_EXGEN, 1, 0, 0, IRQS_DISABLED, 0
+ INT_HANDLER decrementer, 0x900, virt=1, bitmask=IRQS_DISABLED
EXC_VIRT_END(decrementer, 0x4900, 0x80)
TRAMP_KVM(PACA_EXGEN, 0x900)
EXC_COMMON_ASYNC(decrementer_common, 0x900, timer_interrupt)
EXC_REAL_BEGIN(hdecrementer, 0x980, 0x80)
- INT_HANDLER hdecrementer, 0x980, 0, 0, 0, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER hdecrementer, 0x980, hsrr=EXC_HV, kvm=1
EXC_REAL_END(hdecrementer, 0x980, 0x80)
EXC_VIRT_BEGIN(hdecrementer, 0x4980, 0x80)
- INT_HANDLER hdecrementer, 0x980, 0, 0, 1, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER hdecrementer, 0x980, virt=1, hsrr=EXC_HV, kvm=1
EXC_VIRT_END(hdecrementer, 0x4980, 0x80)
TRAMP_KVM_HV(PACA_EXGEN, 0x980)
EXC_COMMON(hdecrementer_common, 0x980, hdec_interrupt)
EXC_REAL_BEGIN(doorbell_super, 0xa00, 0x100)
- INT_HANDLER doorbell_super, 0xa00, 0, 0, 0, EXC_STD, PACA_EXGEN, 1, 0, 0, IRQS_DISABLED, 1
+ INT_HANDLER doorbell_super, 0xa00, bitmask=IRQS_DISABLED, kvm=1
EXC_REAL_END(doorbell_super, 0xa00, 0x100)
EXC_VIRT_BEGIN(doorbell_super, 0x4a00, 0x100)
- INT_HANDLER doorbell_super, 0xa00, 0, 0, 1, EXC_STD, PACA_EXGEN, 1, 0, 0, IRQS_DISABLED, 0
+ INT_HANDLER doorbell_super, 0xa00, virt=1, bitmask=IRQS_DISABLED
EXC_VIRT_END(doorbell_super, 0x4a00, 0x100)
TRAMP_KVM(PACA_EXGEN, 0xa00)
#ifdef CONFIG_PPC_DOORBELL
@@ -1558,20 +1558,20 @@ TRAMP_KVM_BEGIN(do_kvm_0xc00)
EXC_REAL_BEGIN(single_step, 0xd00, 0x100)
- INT_HANDLER single_step, 0xd00, 0, 0, 0, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER single_step, 0xd00, kvm=1
EXC_REAL_END(single_step, 0xd00, 0x100)
EXC_VIRT_BEGIN(single_step, 0x4d00, 0x100)
- INT_HANDLER single_step, 0xd00, 0, 0, 1, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 0
+ INT_HANDLER single_step, 0xd00, virt=1
EXC_VIRT_END(single_step, 0x4d00, 0x100)
TRAMP_KVM(PACA_EXGEN, 0xd00)
EXC_COMMON(single_step_common, 0xd00, single_step_exception)
EXC_REAL_BEGIN(h_data_storage, 0xe00, 0x20)
- INT_HANDLER h_data_storage, 0xe00, 1, 0, 0, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER h_data_storage, 0xe00, ool=1, hsrr=EXC_HV, kvm=1
EXC_REAL_END(h_data_storage, 0xe00, 0x20)
EXC_VIRT_BEGIN(h_data_storage, 0x4e00, 0x20)
- INT_HANDLER h_data_storage, 0xe00, 1, 0, 1, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER h_data_storage, 0xe00, ool=1, virt=1, hsrr=EXC_HV, kvm=1
EXC_VIRT_END(h_data_storage, 0x4e00, 0x20)
TRAMP_KVM_HV_SKIP(PACA_EXGEN, 0xe00)
EXC_COMMON_BEGIN(h_data_storage_common)
@@ -1597,20 +1597,20 @@ ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_TYPE_RADIX)
EXC_REAL_BEGIN(h_instr_storage, 0xe20, 0x20)
- INT_HANDLER h_instr_storage, 0xe20, 1, 0, 0, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER h_instr_storage, 0xe20, ool=1, hsrr=EXC_HV, kvm=1
EXC_REAL_END(h_instr_storage, 0xe20, 0x20)
EXC_VIRT_BEGIN(h_instr_storage, 0x4e20, 0x20)
- INT_HANDLER h_instr_storage, 0xe20, 1, 0, 1, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER h_instr_storage, 0xe20, ool=1, virt=1, hsrr=EXC_HV, kvm=1
EXC_VIRT_END(h_instr_storage, 0x4e20, 0x20)
TRAMP_KVM_HV(PACA_EXGEN, 0xe20)
EXC_COMMON(h_instr_storage_common, 0xe20, unknown_exception)
EXC_REAL_BEGIN(emulation_assist, 0xe40, 0x20)
- INT_HANDLER emulation_assist, 0xe40, 1, 0, 0, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER emulation_assist, 0xe40, ool=1, hsrr=EXC_HV, kvm=1
EXC_REAL_END(emulation_assist, 0xe40, 0x20)
EXC_VIRT_BEGIN(emulation_assist, 0x4e40, 0x20)
- INT_HANDLER emulation_assist, 0xe40, 1, 0, 1, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER emulation_assist, 0xe40, ool=1, virt=1, hsrr=EXC_HV, kvm=1
EXC_VIRT_END(emulation_assist, 0x4e40, 0x20)
TRAMP_KVM_HV(PACA_EXGEN, 0xe40)
EXC_COMMON(emulation_assist_common, 0xe40, emulation_assist_interrupt)
@@ -1622,7 +1622,7 @@ EXC_COMMON(emulation_assist_common, 0xe40, emulation_assist_interrupt)
* mode.
*/
EXC_REAL_BEGIN(hmi_exception, 0xe60, 0x20)
- INT_HANDLER hmi_exception, 0xe60, 1, 1, 0, EXC_HV, PACA_EXGEN, 0, 0, 0, 0, 1
+ INT_HANDLER hmi_exception, 0xe60, ool=1, early=1, hsrr=EXC_HV, ri=0, kvm=1
EXC_REAL_END(hmi_exception, 0xe60, 0x20)
EXC_VIRT_NONE(0x4e60, 0x20)
TRAMP_KVM_HV(PACA_EXGEN, 0xe60)
@@ -1652,7 +1652,7 @@ EXC_COMMON_BEGIN(hmi_exception_early_common)
* firmware.
*/
EXCEPTION_RESTORE_REGS EXC_HV
- INT_HANDLER hmi_exception, 0xe60, 0, 0, 0, EXC_HV, PACA_EXGEN, 1, 0, 0, IRQS_DISABLED, 1
+ INT_HANDLER hmi_exception, 0xe60, hsrr=EXC_HV, bitmask=IRQS_DISABLED, kvm=1
EXC_COMMON_BEGIN(hmi_exception_common)
EXCEPTION_COMMON(PACA_EXGEN, 0xe60)
@@ -1666,10 +1666,10 @@ EXC_COMMON_BEGIN(hmi_exception_common)
EXC_REAL_BEGIN(h_doorbell, 0xe80, 0x20)
- INT_HANDLER h_doorbell, 0xe80, 1, 0, 0, EXC_HV, PACA_EXGEN, 1, 0, 0, IRQS_DISABLED, 1
+ INT_HANDLER h_doorbell, 0xe80, ool=1, hsrr=EXC_HV, bitmask=IRQS_DISABLED, kvm=1
EXC_REAL_END(h_doorbell, 0xe80, 0x20)
EXC_VIRT_BEGIN(h_doorbell, 0x4e80, 0x20)
- INT_HANDLER h_doorbell, 0xe80, 1, 0, 1, EXC_HV, PACA_EXGEN, 1, 0, 0, IRQS_DISABLED, 1
+ INT_HANDLER h_doorbell, 0xe80, ool=1, virt=1, hsrr=EXC_HV, bitmask=IRQS_DISABLED, kvm=1
EXC_VIRT_END(h_doorbell, 0x4e80, 0x20)
TRAMP_KVM_HV(PACA_EXGEN, 0xe80)
#ifdef CONFIG_PPC_DOORBELL
@@ -1680,10 +1680,10 @@ EXC_COMMON_ASYNC(h_doorbell_common, 0xe80, unknown_exception)
EXC_REAL_BEGIN(h_virt_irq, 0xea0, 0x20)
- INT_HANDLER h_virt_irq, 0xea0, 1, 0, 0, EXC_HV, PACA_EXGEN, 1, 0, 0, IRQS_DISABLED, 1
+ INT_HANDLER h_virt_irq, 0xea0, ool=1, hsrr=EXC_HV, bitmask=IRQS_DISABLED, kvm=1
EXC_REAL_END(h_virt_irq, 0xea0, 0x20)
EXC_VIRT_BEGIN(h_virt_irq, 0x4ea0, 0x20)
- INT_HANDLER h_virt_irq, 0xea0, 1, 0, 1, EXC_HV, PACA_EXGEN, 1, 0, 0, IRQS_DISABLED, 1
+ INT_HANDLER h_virt_irq, 0xea0, ool=1, virt=1, hsrr=EXC_HV, bitmask=IRQS_DISABLED, kvm=1
EXC_VIRT_END(h_virt_irq, 0x4ea0, 0x20)
TRAMP_KVM_HV(PACA_EXGEN, 0xea0)
EXC_COMMON_ASYNC(h_virt_irq_common, 0xea0, do_IRQ)
@@ -1696,20 +1696,20 @@ EXC_VIRT_NONE(0x4ee0, 0x20)
EXC_REAL_BEGIN(performance_monitor, 0xf00, 0x20)
- INT_HANDLER performance_monitor, 0xf00, 1, 0, 0, EXC_STD, PACA_EXGEN, 1, 0, 0, IRQS_PMI_DISABLED, 1
+ INT_HANDLER performance_monitor, 0xf00, ool=1, bitmask=IRQS_PMI_DISABLED, kvm=1
EXC_REAL_END(performance_monitor, 0xf00, 0x20)
EXC_VIRT_BEGIN(performance_monitor, 0x4f00, 0x20)
- INT_HANDLER performance_monitor, 0xf00, 1, 0, 1, EXC_STD, PACA_EXGEN, 1, 0, 0, IRQS_PMI_DISABLED, 0
+ INT_HANDLER performance_monitor, 0xf00, ool=1, virt=1, bitmask=IRQS_PMI_DISABLED
EXC_VIRT_END(performance_monitor, 0x4f00, 0x20)
TRAMP_KVM(PACA_EXGEN, 0xf00)
EXC_COMMON_ASYNC(performance_monitor_common, 0xf00, performance_monitor_exception)
EXC_REAL_BEGIN(altivec_unavailable, 0xf20, 0x20)
- INT_HANDLER altivec_unavailable, 0xf20, 1, 0, 0, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER altivec_unavailable, 0xf20, ool=1, kvm=1
EXC_REAL_END(altivec_unavailable, 0xf20, 0x20)
EXC_VIRT_BEGIN(altivec_unavailable, 0x4f20, 0x20)
- INT_HANDLER altivec_unavailable, 0xf20, 1, 0, 1, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 0
+ INT_HANDLER altivec_unavailable, 0xf20, ool=1, virt=1
EXC_VIRT_END(altivec_unavailable, 0x4f20, 0x20)
TRAMP_KVM(PACA_EXGEN, 0xf20)
EXC_COMMON_BEGIN(altivec_unavailable_common)
@@ -1747,10 +1747,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
EXC_REAL_BEGIN(vsx_unavailable, 0xf40, 0x20)
- INT_HANDLER vsx_unavailable, 0xf40, 1, 0, 0, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER vsx_unavailable, 0xf40, ool=1, kvm=1
EXC_REAL_END(vsx_unavailable, 0xf40, 0x20)
EXC_VIRT_BEGIN(vsx_unavailable, 0x4f40, 0x20)
- INT_HANDLER vsx_unavailable, 0xf40, 1, 0, 1, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 0
+ INT_HANDLER vsx_unavailable, 0xf40, ool=1, virt=1
EXC_VIRT_END(vsx_unavailable, 0x4f40, 0x20)
TRAMP_KVM(PACA_EXGEN, 0xf40)
EXC_COMMON_BEGIN(vsx_unavailable_common)
@@ -1787,20 +1787,20 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
EXC_REAL_BEGIN(facility_unavailable, 0xf60, 0x20)
- INT_HANDLER facility_unavailable, 0xf60, 1, 0, 0, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER facility_unavailable, 0xf60, ool=1, kvm=1
EXC_REAL_END(facility_unavailable, 0xf60, 0x20)
EXC_VIRT_BEGIN(facility_unavailable, 0x4f60, 0x20)
- INT_HANDLER facility_unavailable, 0xf60, 1, 0, 1, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 0
+ INT_HANDLER facility_unavailable, 0xf60, ool=1, virt=1
EXC_VIRT_END(facility_unavailable, 0x4f60, 0x20)
TRAMP_KVM(PACA_EXGEN, 0xf60)
EXC_COMMON(facility_unavailable_common, 0xf60, facility_unavailable_exception)
EXC_REAL_BEGIN(h_facility_unavailable, 0xf80, 0x20)
- INT_HANDLER h_facility_unavailable, 0xf80, 1, 0, 0, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER h_facility_unavailable, 0xf80, ool=1, hsrr=EXC_HV, kvm=1
EXC_REAL_END(h_facility_unavailable, 0xf80, 0x20)
EXC_VIRT_BEGIN(h_facility_unavailable, 0x4f80, 0x20)
- INT_HANDLER h_facility_unavailable, 0xf80, 1, 0, 1, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER h_facility_unavailable, 0xf80, ool=1, virt=1, hsrr=EXC_HV, kvm=1
EXC_VIRT_END(h_facility_unavailable, 0x4f80, 0x20)
TRAMP_KVM_HV(PACA_EXGEN, 0xf80)
EXC_COMMON(h_facility_unavailable_common, 0xf80, facility_unavailable_exception)
@@ -1820,7 +1820,7 @@ EXC_VIRT_NONE(0x5100, 0x100)
#ifdef CONFIG_CBE_RAS
EXC_REAL_BEGIN(cbe_system_error, 0x1200, 0x100)
- INT_HANDLER cbe_system_error, 0x1200, 1, 0, 0, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER cbe_system_error, 0x1200, ool=1, hsrr=EXC_HV, kvm=1
EXC_REAL_END(cbe_system_error, 0x1200, 0x100)
EXC_VIRT_NONE(0x5200, 0x100)
TRAMP_KVM_HV_SKIP(PACA_EXGEN, 0x1200)
@@ -1832,10 +1832,10 @@ EXC_VIRT_NONE(0x5200, 0x100)
EXC_REAL_BEGIN(instruction_breakpoint, 0x1300, 0x100)
- INT_HANDLER instruction_breakpoint, 0x1300, 0, 0, 0, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER instruction_breakpoint, 0x1300, kvm=1
EXC_REAL_END(instruction_breakpoint, 0x1300, 0x100)
EXC_VIRT_BEGIN(instruction_breakpoint, 0x5300, 0x100)
- INT_HANDLER instruction_breakpoint, 0x1300, 0, 0, 1, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 0
+ INT_HANDLER instruction_breakpoint, 0x1300, virt=1
EXC_VIRT_END(instruction_breakpoint, 0x5300, 0x100)
TRAMP_KVM_SKIP(PACA_EXGEN, 0x1300)
EXC_COMMON(instruction_breakpoint_common, 0x1300, instruction_breakpoint_exception)
@@ -1845,7 +1845,7 @@ EXC_REAL_NONE(0x1400, 0x100)
EXC_VIRT_NONE(0x5400, 0x100)
EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100)
- INT_HANDLER denorm_exception_hv, 0x1500, 0, 2, 0, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 0
+ INT_HANDLER denorm_exception_hv, 0x1500, early=2, hsrr=EXC_HV
#ifdef CONFIG_PPC_DENORMALISATION
mfspr r10,SPRN_HSRR1
andis. r10,r10,(HSRR1_DENORM)@h /* denorm? */
@@ -1939,7 +1939,7 @@ EXC_COMMON(denorm_common, 0x1500, unknown_exception)
#ifdef CONFIG_CBE_RAS
EXC_REAL_BEGIN(cbe_maintenance, 0x1600, 0x100)
- INT_HANDLER cbe_maintenance, 0x1600, 1, 0, 0, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER cbe_maintenance, 0x1600, ool=1, hsrr=EXC_HV, kvm=1
EXC_REAL_END(cbe_maintenance, 0x1600, 0x100)
EXC_VIRT_NONE(0x5600, 0x100)
TRAMP_KVM_HV_SKIP(PACA_EXGEN, 0x1600)
@@ -1951,10 +1951,10 @@ EXC_VIRT_NONE(0x5600, 0x100)
EXC_REAL_BEGIN(altivec_assist, 0x1700, 0x100)
- INT_HANDLER altivec_assist, 0x1700, 0, 0, 0, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER altivec_assist, 0x1700, kvm=1
EXC_REAL_END(altivec_assist, 0x1700, 0x100)
EXC_VIRT_BEGIN(altivec_assist, 0x5700, 0x100)
- INT_HANDLER altivec_assist, 0x1700, 0, 0, 1, EXC_STD, PACA_EXGEN, 1, 0, 0, 0, 0
+ INT_HANDLER altivec_assist, 0x1700, virt=1
EXC_VIRT_END(altivec_assist, 0x5700, 0x100)
TRAMP_KVM(PACA_EXGEN, 0x1700)
#ifdef CONFIG_ALTIVEC
@@ -1966,7 +1966,7 @@ EXC_COMMON(altivec_assist_common, 0x1700, unknown_exception)
#ifdef CONFIG_CBE_RAS
EXC_REAL_BEGIN(cbe_thermal, 0x1800, 0x100)
- INT_HANDLER cbe_thermal, 0x1800, 1, 0, 0, EXC_HV, PACA_EXGEN, 1, 0, 0, 0, 1
+ INT_HANDLER cbe_thermal, 0x1800, ool=1, hsrr=EXC_HV, kvm=1
EXC_REAL_END(cbe_thermal, 0x1800, 0x100)
EXC_VIRT_NONE(0x5800, 0x100)
TRAMP_KVM_HV_SKIP(PACA_EXGEN, 0x1800)
--
2.21.0
^ permalink raw reply related
* Singaporean Mr. Teo En Ming's Refugee Seeking Attempts
From: Turritopsis Dohrnii Teo En Ming @ 2019-08-30 2:36 UTC (permalink / raw)
To: linuxppc-dev@lists.ozlabs.org; +Cc: Turritopsis Dohrnii Teo En Ming
Subject: Singaporean Mr. Teo En Ming's Refugee Seeking Attempts
In reverse chronological order:
[1] Petition to the Government of Taiwan for Refugee Status, 5th August 2019 Monday
Photo #1: At the building of the National Immigration Agency, Ministry of the Interior, Taipei, Taiwan, 5th August 2019
Photo #2: Queue ticket at the National Immigration Agency, Ministry of the Interior, Taipei, Taiwan, 5th August 2019
Photo #3: Submission of documents/petition to the National Immigration Agency, Ministry of the Interior, Taipei, Taiwan, 5th August 2019
Photos #4 and #5: Acknowledgement of Receipt for the submission of documents/petition from the National Immigration Agency, Ministry of the Interior, Taipei, Taiwan, 5th August 2019
References:
(a) Petition to the Government of Taiwan for Refugee Status, 5th August 2019 Monday (Blogspot)
Link: https://tdtemcerts.blogspot.sg/2019/08/petition-to-government-of-taiwan-for.html
(b) Petition to the Government of Taiwan for Refugee Status, 5th August 2019 Monday (Wordpress)
Link: https://tdtemcerts.wordpress.com/2019/08/23/petition-to-the-government-of-taiwan-for-refugee-status/
[2] Application for Refugee Status at the United Nations Refugee Agency, Bangkok, Thailand, 21st March 2017 Tuesday
References:
(a) [YOUTUBE] Vlog: The Road to Application for Refugee Status at UNHCR Bangkok
Link: https://www.youtube.com/watch?v=utpuAa1eUNI
YouTube video Published on March 22nd, 2017
-----BEGIN EMAIL SIGNATURE-----
The Gospel for all Targeted Individuals (TIs):
[The New York Times] Microwave Weapons Are Prime Suspect in Ills of
U.S. Embassy Workers
Link: https://www.nytimes.com/2018/09/01/science/sonic-attack-cuba-microwave.html
********************************************************************************************
Singaporean Mr. Turritopsis Dohrnii Teo En Ming's Academic
Qualifications as at 14 Feb 2019
[1] https://tdtemcerts.wordpress.com/
[2] https://tdtemcerts.blogspot.sg/
[3] https://www.scribd.com/user/270125049/Teo-En-Ming
-----END EMAIL SIGNATURE-----
^ permalink raw reply
* Re: [PATCH v2] powerpc/mm: Implement STRICT_MODULE_RWX
From: Russell Currey @ 2019-08-30 3:22 UTC (permalink / raw)
To: Christophe Leroy, linuxppc-dev; +Cc: kernel-hardening
In-Reply-To: <6bf5e5e3-1dfe-05fe-d736-7c846b8ac6f6@c-s.fr>
On Wed, 2019-08-28 at 15:54 +0200, Christophe Leroy wrote:
> Any plan to getting this applied soon ?
Hey Christophe,
I'm still working on it. Had to rework it for a few reasons, and it
exposed a bug somewhere else. Hope to have another version out soon.
- Russell
>
> Christophe
^ permalink raw reply
* Re: [PATCH] powerpc: Replace GPL boilerplate with SPDX identifiers
From: Russell Currey @ 2019-08-30 3:23 UTC (permalink / raw)
To: Thomas Huth, Benjamin Herrenschmidt, Paul Mackerras,
Michael Ellerman, linuxppc-dev
Cc: Sam Bobroff, Oliver O'Halloran, linux-kernel, Arnd Bergmann
In-Reply-To: <20190828060737.32531-1-thuth@redhat.com>
On Wed, 2019-08-28 at 08:07 +0200, Thomas Huth wrote:
> The FSF does not reside in "675 Mass Ave, Cambridge" anymore...
> let's simply use proper SPDX identifiers instead.
>
> Signed-off-by: Thomas Huth <thuth@redhat.com>
Acked-by: Russell Currey <ruscur@russell.cc>
^ permalink raw reply
* [PATCH v6 1/2] powerpc/xmon: Allow listing and clearing breakpoints in read-only mode
From: Christopher M. Riedl @ 2019-08-30 3:37 UTC (permalink / raw)
To: linuxppc-dev, kernel-hardening; +Cc: ajd, Daniel Axtens
In-Reply-To: <20190830033744.1392-1-cmr@informatik.wtf>
Read-only mode should not prevent listing and clearing any active
breakpoints.
Tested-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Christopher M. Riedl <cmr@informatik.wtf>
---
arch/powerpc/xmon/xmon.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index d0620d762a5a..ed94de614938 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -1045,10 +1045,6 @@ cmds(struct pt_regs *excp)
set_lpp_cmd();
break;
case 'b':
- if (xmon_is_ro) {
- printf(xmon_ro_msg);
- break;
- }
bpt_cmds();
break;
case 'C':
@@ -1317,11 +1313,16 @@ bpt_cmds(void)
struct bpt *bp;
cmd = inchar();
+
switch (cmd) {
#ifndef CONFIG_PPC_8xx
static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
int mode;
case 'd': /* bd - hardware data breakpoint */
+ if (xmon_is_ro) {
+ printf(xmon_ro_msg);
+ break;
+ }
if (!ppc_breakpoint_available()) {
printf("Hardware data breakpoint not supported on this cpu\n");
break;
@@ -1349,6 +1350,10 @@ bpt_cmds(void)
break;
case 'i': /* bi - hardware instr breakpoint */
+ if (xmon_is_ro) {
+ printf(xmon_ro_msg);
+ break;
+ }
if (!cpu_has_feature(CPU_FTR_ARCH_207S)) {
printf("Hardware instruction breakpoint "
"not supported on this cpu\n");
@@ -1407,7 +1412,8 @@ bpt_cmds(void)
break;
}
termch = cmd;
- if (!scanhex(&a)) {
+
+ if (xmon_is_ro || !scanhex(&a)) {
/* print all breakpoints */
printf(" type address\n");
if (dabr.enabled) {
--
2.23.0
^ permalink raw reply related
* [PATCH v6 0/2] Restrict xmon when kernel is locked down
From: Christopher M. Riedl @ 2019-08-30 3:37 UTC (permalink / raw)
To: linuxppc-dev, kernel-hardening; +Cc: ajd
Xmon should be either fully or partially disabled depending on the
kernel lockdown state.
Put xmon into read-only mode for lockdown=integrity and completely
disable xmon when lockdown=confidentiality. Since this can occur
dynamically, there may be pre-existing, active breakpoints in xmon when
transitioning into read-only mode. These breakpoints will still trigger,
so allow them to be listed and cleared using xmon.
Changes since v5:
- Do not spam print messages when attempting to enter xmon when
lockdown=confidentiality
Changes since v4:
- Move lockdown state checks into xmon_core
- Allow clearing of breakpoints in xmon read-only mode
- Test simple scenarios (combinations of xmon and lockdown cmdline
options, setting breakpoints and changing lockdown state, etc) in
QEMU and on an actual POWER8 VM
- Rebase onto security/next-lockdown
b602614a81078bf29c82b2671bb96a63488f68d6
Changes since v3:
- Allow active breakpoints to be shown/listed in read-only mode
Changes since v2:
- Rebased onto v36 of https://patchwork.kernel.org/cover/11049461/
(based on: f632a8170a6b667ee4e3f552087588f0fe13c4bb)
- Do not clear existing breakpoints when transitioning from
lockdown=none to lockdown=integrity
- Remove line continuation and dangling quote (confuses checkpatch.pl)
from the xmon command help/usage string
Christopher M. Riedl (2):
powerpc/xmon: Allow listing and clearing breakpoints in read-only mode
powerpc/xmon: Restrict when kernel is locked down
arch/powerpc/xmon/xmon.c | 108 +++++++++++++++++++++++++++--------
include/linux/security.h | 2 +
security/lockdown/lockdown.c | 2 +
3 files changed, 87 insertions(+), 25 deletions(-)
--
2.23.0
^ permalink raw reply
* [PATCH v6 2/2] powerpc/xmon: Restrict when kernel is locked down
From: Christopher M. Riedl @ 2019-08-30 3:37 UTC (permalink / raw)
To: linuxppc-dev, kernel-hardening; +Cc: ajd, Daniel Axtens
In-Reply-To: <20190830033744.1392-1-cmr@informatik.wtf>
Xmon should be either fully or partially disabled depending on the
kernel lockdown state.
Put xmon into read-only mode for lockdown=integrity and prevent user
entry into xmon when lockdown=confidentiality. Xmon checks the lockdown
state on every attempted entry:
(1) during early xmon'ing
(2) when triggered via sysrq
(3) when toggled via debugfs
(4) when triggered via a previously enabled breakpoint
The following lockdown state transitions are handled:
(1) lockdown=none -> lockdown=integrity
set xmon read-only mode
(2) lockdown=none -> lockdown=confidentiality
clear all breakpoints, set xmon read-only mode,
prevent user re-entry into xmon
(3) lockdown=integrity -> lockdown=confidentiality
clear all breakpoints, set xmon read-only mode,
prevent user re-entry into xmon
Suggested-by: Andrew Donnellan <ajd@linux.ibm.com>
Tested-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Christopher M. Riedl <cmr@informatik.wtf>
---
arch/powerpc/xmon/xmon.c | 92 ++++++++++++++++++++++++++++--------
include/linux/security.h | 2 +
security/lockdown/lockdown.c | 2 +
3 files changed, 76 insertions(+), 20 deletions(-)
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index ed94de614938..335718d0b777 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -25,6 +25,7 @@
#include <linux/nmi.h>
#include <linux/ctype.h>
#include <linux/highmem.h>
+#include <linux/security.h>
#include <asm/debugfs.h>
#include <asm/ptrace.h>
@@ -187,6 +188,8 @@ static void dump_tlb_44x(void);
static void dump_tlb_book3e(void);
#endif
+static void clear_all_bpt(void);
+
#ifdef CONFIG_PPC64
#define REG "%.16lx"
#else
@@ -283,10 +286,38 @@ Commands:\n\
" U show uptime information\n"
" ? help\n"
" # n limit output to n lines per page (for dp, dpa, dl)\n"
-" zr reboot\n\
- zh halt\n"
+" zr reboot\n"
+" zh halt\n"
;
+#ifdef CONFIG_SECURITY
+static bool xmon_is_locked_down(void)
+{
+ static bool lockdown;
+
+ if (!lockdown) {
+ lockdown = !!security_locked_down(LOCKDOWN_XMON_RW);
+ if (lockdown) {
+ printf("xmon: Disabled due to kernel lockdown\n");
+ xmon_is_ro = true;
+ }
+ }
+
+ if (!xmon_is_ro) {
+ xmon_is_ro = !!security_locked_down(LOCKDOWN_XMON_WR);
+ if (xmon_is_ro)
+ printf("xmon: Read-only due to kernel lockdown\n");
+ }
+
+ return lockdown;
+}
+#else /* CONFIG_SECURITY */
+static inline bool xmon_is_locked_down(void)
+{
+ return false;
+}
+#endif
+
static struct pt_regs *xmon_regs;
static inline void sync(void)
@@ -438,7 +469,10 @@ static bool wait_for_other_cpus(int ncpus)
return false;
}
-#endif /* CONFIG_SMP */
+#else /* CONFIG_SMP */
+static inline void get_output_lock(void) {}
+static inline void release_output_lock(void) {}
+#endif
static inline int unrecoverable_excp(struct pt_regs *regs)
{
@@ -455,6 +489,7 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
int cmd = 0;
struct bpt *bp;
long recurse_jmp[JMP_BUF_LEN];
+ bool locked_down;
unsigned long offset;
unsigned long flags;
#ifdef CONFIG_SMP
@@ -465,6 +500,8 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
local_irq_save(flags);
hard_irq_disable();
+ locked_down = xmon_is_locked_down();
+
tracing_enabled = tracing_is_on();
tracing_off();
@@ -516,7 +553,8 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
if (!fromipi) {
get_output_lock();
- excprint(regs);
+ if (!locked_down)
+ excprint(regs);
if (bp) {
printf("cpu 0x%x stopped at breakpoint 0x%tx (",
cpu, BP_NUM(bp));
@@ -568,10 +606,14 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
}
remove_bpts();
disable_surveillance();
- /* for breakpoint or single step, print the current instr. */
- if (bp || TRAP(regs) == 0xd00)
- ppc_inst_dump(regs->nip, 1, 0);
- printf("enter ? for help\n");
+
+ if (!locked_down) {
+ /* for breakpoint or single step, print curr insn */
+ if (bp || TRAP(regs) == 0xd00)
+ ppc_inst_dump(regs->nip, 1, 0);
+ printf("enter ? for help\n");
+ }
+
mb();
xmon_gate = 1;
barrier();
@@ -595,8 +637,9 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
spin_cpu_relax();
touch_nmi_watchdog();
} else {
- cmd = cmds(regs);
- if (cmd != 0) {
+ if (!locked_down)
+ cmd = cmds(regs);
+ if (locked_down || cmd != 0) {
/* exiting xmon */
insert_bpts();
xmon_gate = 0;
@@ -633,13 +676,16 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
"can't continue\n");
remove_bpts();
disable_surveillance();
- /* for breakpoint or single step, print the current instr. */
- if (bp || TRAP(regs) == 0xd00)
- ppc_inst_dump(regs->nip, 1, 0);
- printf("enter ? for help\n");
+ if (!locked_down) {
+ /* for breakpoint or single step, print current insn */
+ if (bp || TRAP(regs) == 0xd00)
+ ppc_inst_dump(regs->nip, 1, 0);
+ printf("enter ? for help\n");
+ }
}
- cmd = cmds(regs);
+ if (!locked_down)
+ cmd = cmds(regs);
insert_bpts();
in_xmon = 0;
@@ -668,7 +714,10 @@ static int xmon_core(struct pt_regs *regs, int fromipi)
}
}
#endif
- insert_cpu_bpts();
+ if (locked_down)
+ clear_all_bpt();
+ else
+ insert_cpu_bpts();
touch_nmi_watchdog();
local_irq_restore(flags);
@@ -3768,7 +3817,6 @@ static int __init setup_xmon_sysrq(void)
device_initcall(setup_xmon_sysrq);
#endif /* CONFIG_MAGIC_SYSRQ */
-#ifdef CONFIG_DEBUG_FS
static void clear_all_bpt(void)
{
int i;
@@ -3786,18 +3834,22 @@ static void clear_all_bpt(void)
iabr = NULL;
dabr.enabled = 0;
}
-
- printf("xmon: All breakpoints cleared\n");
}
+#ifdef CONFIG_DEBUG_FS
static int xmon_dbgfs_set(void *data, u64 val)
{
xmon_on = !!val;
xmon_init(xmon_on);
/* make sure all breakpoints removed when disabling */
- if (!xmon_on)
+ if (!xmon_on) {
clear_all_bpt();
+ get_output_lock();
+ printf("xmon: All breakpoints cleared\n");
+ release_output_lock();
+ }
+
return 0;
}
diff --git a/include/linux/security.h b/include/linux/security.h
index 429f9f03372b..ba9d308689b6 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -116,12 +116,14 @@ enum lockdown_reason {
LOCKDOWN_MODULE_PARAMETERS,
LOCKDOWN_MMIOTRACE,
LOCKDOWN_DEBUGFS,
+ LOCKDOWN_XMON_WR,
LOCKDOWN_INTEGRITY_MAX,
LOCKDOWN_KCORE,
LOCKDOWN_KPROBES,
LOCKDOWN_BPF_READ,
LOCKDOWN_PERF,
LOCKDOWN_TRACEFS,
+ LOCKDOWN_XMON_RW,
LOCKDOWN_CONFIDENTIALITY_MAX,
};
diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
index 0068cec77c05..db85182d3f11 100644
--- a/security/lockdown/lockdown.c
+++ b/security/lockdown/lockdown.c
@@ -31,12 +31,14 @@ static char *lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1] = {
[LOCKDOWN_MODULE_PARAMETERS] = "unsafe module parameters",
[LOCKDOWN_MMIOTRACE] = "unsafe mmio",
[LOCKDOWN_DEBUGFS] = "debugfs access",
+ [LOCKDOWN_XMON_WR] = "xmon write access",
[LOCKDOWN_INTEGRITY_MAX] = "integrity",
[LOCKDOWN_KCORE] = "/proc/kcore access",
[LOCKDOWN_KPROBES] = "use of kprobes",
[LOCKDOWN_BPF_READ] = "use of bpf to read kernel RAM",
[LOCKDOWN_PERF] = "unsafe use of perf",
[LOCKDOWN_TRACEFS] = "use of tracefs",
+ [LOCKDOWN_XMON_RW] = "xmon read and write access",
[LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
};
--
2.23.0
^ permalink raw reply related
* Re: [PATCH v7 1/7] kvmppc: Driver to manage pages of secure guest
From: Bharata B Rao @ 2019-08-30 3:42 UTC (permalink / raw)
To: Christoph Hellwig
Cc: linuxram, cclaudio, kvm-ppc, linux-mm, jglisse, aneesh.kumar,
paulus, sukadev, linuxppc-dev
In-Reply-To: <20190829083810.GA13039@lst.de>
On Thu, Aug 29, 2019 at 10:38:10AM +0200, Christoph Hellwig wrote:
> On Thu, Aug 22, 2019 at 03:56:14PM +0530, Bharata B Rao wrote:
> > +/*
> > + * Bits 60:56 in the rmap entry will be used to identify the
> > + * different uses/functions of rmap.
> > + */
> > +#define KVMPPC_RMAP_DEVM_PFN (0x2ULL << 56)
>
> How did you come up with this specific value?
Different usage types of RMAP array are being defined.
https://patchwork.ozlabs.org/patch/1149791/
The above value is reserved for device pfn usage.
>
> > +
> > +static inline bool kvmppc_rmap_is_devm_pfn(unsigned long pfn)
> > +{
> > + return !!(pfn & KVMPPC_RMAP_DEVM_PFN);
> > +}
>
> No need for !! when returning a bool. Also the helper seems a little
> pointless, just opencoding it would make the code more readable in my
> opinion.
I expect similar routines for other usages of RMAP to come up.
>
> > +#ifdef CONFIG_PPC_UV
> > +extern int kvmppc_devm_init(void);
> > +extern void kvmppc_devm_free(void);
>
> There is no need for extern in a function declaration.
>
> > +static int
> > +kvmppc_devm_migrate_alloc_and_copy(struct migrate_vma *mig,
> > + unsigned long *rmap, unsigned long gpa,
> > + unsigned int lpid, unsigned long page_shift)
> > +{
> > + struct page *spage = migrate_pfn_to_page(*mig->src);
> > + unsigned long pfn = *mig->src >> MIGRATE_PFN_SHIFT;
> > + struct page *dpage;
> > +
> > + *mig->dst = 0;
> > + if (!spage || !(*mig->src & MIGRATE_PFN_MIGRATE))
> > + return 0;
> > +
> > + dpage = kvmppc_devm_get_page(rmap, gpa, lpid);
> > + if (!dpage)
> > + return -EINVAL;
> > +
> > + if (spage)
> > + uv_page_in(lpid, pfn << page_shift, gpa, 0, page_shift);
> > +
> > + *mig->dst = migrate_pfn(page_to_pfn(dpage)) | MIGRATE_PFN_LOCKED;
> > + return 0;
> > +}
>
> I think you can just merge this trivial helper into the only caller.
Yes I can, but felt it is nicely abstracted out to a function right now.
>
> > +static int
> > +kvmppc_devm_fault_migrate_alloc_and_copy(struct migrate_vma *mig,
> > + unsigned long page_shift)
> > +{
> > + struct page *dpage, *spage;
> > + struct kvmppc_devm_page_pvt *pvt;
> > + unsigned long pfn;
> > + int ret;
> > +
> > + spage = migrate_pfn_to_page(*mig->src);
> > + if (!spage || !(*mig->src & MIGRATE_PFN_MIGRATE))
> > + return 0;
> > + if (!is_zone_device_page(spage))
> > + return 0;
> > +
> > + dpage = alloc_page_vma(GFP_HIGHUSER, mig->vma, mig->start);
> > + if (!dpage)
> > + return -EINVAL;
> > + lock_page(dpage);
> > + pvt = spage->zone_device_data;
> > +
> > + pfn = page_to_pfn(dpage);
> > + ret = uv_page_out(pvt->lpid, pfn << page_shift, pvt->gpa, 0,
> > + page_shift);
> > + if (ret == U_SUCCESS)
> > + *mig->dst = migrate_pfn(pfn) | MIGRATE_PFN_LOCKED;
> > + else {
> > + unlock_page(dpage);
> > + __free_page(dpage);
> > + }
> > + return ret;
> > +}
>
> Here we actually have two callers, but they have a fair amount of
> duplicate code in them. I think you want to move that common
> code (including setting up the migrate_vma structure) into this
> function and maybe also give it a more descriptive name.
Sure, I will give this a try. The name is already very descriptive, will
come up with an appropriate name.
BTW this file and the fuction prefixes in this file started out with
kvmppc_hmm, switched to kvmppc_devm when HMM routines weren't used anymore.
Now with the use of only non-dev versions, planning to swtich to
kvmppc_uvmem_
>
> > +static void kvmppc_devm_page_free(struct page *page)
> > +{
> > + unsigned long pfn = page_to_pfn(page);
> > + unsigned long flags;
> > + struct kvmppc_devm_page_pvt *pvt;
> > +
> > + spin_lock_irqsave(&kvmppc_devm_pfn_lock, flags);
> > + pvt = page->zone_device_data;
> > + page->zone_device_data = NULL;
> > +
> > + bitmap_clear(kvmppc_devm_pfn_bitmap,
> > + pfn - (kvmppc_devm_pgmap.res.start >> PAGE_SHIFT), 1);
>
> Nit: I'd just initialize pfn to the value you want from the start.
> That makes the code a little easier to read, and keeps a tiny bit more
> code outside the spinlock.
>
> unsigned long pfn = page_to_pfn(page) -
> (kvmppc_devm_pgmap.res.start >> PAGE_SHIFT);
>
> ..
>
> bitmap_clear(kvmppc_devm_pfn_bitmap, pfn, 1);
Sure.
>
>
> > + kvmppc_devm_pgmap.type = MEMORY_DEVICE_PRIVATE;
> > + kvmppc_devm_pgmap.res = *res;
> > + kvmppc_devm_pgmap.ops = &kvmppc_devm_ops;
> > + addr = memremap_pages(&kvmppc_devm_pgmap, -1);
>
> This -1 should be NUMA_NO_NODE for clarity.
Right.
Regards,
Bharata.
^ permalink raw reply
* Re: [PATCH v2 1/2] kasan: support instrumented bitops combined with generic bitops
From: Daniel Axtens @ 2019-08-30 5:11 UTC (permalink / raw)
To: christophe.leroy, linux-s390, linux-arch, x86, linuxppc-dev; +Cc: kasan-dev
In-Reply-To: <20190820024941.12640-1-dja@axtens.net>
Daniel Axtens <dja@axtens.net> writes:
> Currently bitops-instrumented.h assumes that the architecture provides
> atomic, non-atomic and locking bitops (e.g. both set_bit and __set_bit).
> This is true on x86 and s390, but is not always true: there is a
> generic bitops/non-atomic.h header that provides generic non-atomic
> operations, and also a generic bitops/lock.h for locking operations.
>
> powerpc uses the generic non-atomic version, so it does not have it's
> own e.g. __set_bit that could be renamed arch___set_bit.
>
> Split up bitops-instrumented.h to mirror the atomic/non-atomic/lock
> split. This allows arches to only include the headers where they
> have arch-specific versions to rename. Update x86 and s390.
This patch should not cause any functional change on either arch.
To verify, I have compiled kernels with and without these. With the
appropriate setting of environment variables and the general assorted
mucking around required for reproducible builds, I have tested:
- s390, without kasan - byte-for-byte identical vmlinux before and after
- x86, without kasan - byte-for-byte identical vmlinux before and after
- s390, inline kasan - byte-for-byte identical vmlinux before and after
- x86, inline kasan - 3 functions in drivers/rtc/dev.o are reordered,
build-id and __ex_table differ, rest is unchanged
The kernels were based on defconfigs. I disabled debug info (as that
obviously changes with code being rearranged) and initrd support (as the
cpio wrapper doesn't seem to take KBUILD_BUILD_TIMESTAMP but the current
time, and that screws things up).
I wouldn't read too much in to the weird result on x86 with inline
kasan: the code I moved about is compiled even without KASAN enabled.
Regards,
Daniel
>
> (The generic operations are automatically instrumented because they're
> written in C, not asm.)
>
> Suggested-by: Christophe Leroy <christophe.leroy@c-s.fr>
> Reviewed-by: Christophe Leroy <christophe.leroy@c-s.fr>
> Signed-off-by: Daniel Axtens <dja@axtens.net>
> ---
> Documentation/core-api/kernel-api.rst | 17 +-
> arch/s390/include/asm/bitops.h | 4 +-
> arch/x86/include/asm/bitops.h | 4 +-
> include/asm-generic/bitops-instrumented.h | 263 ------------------
> .../asm-generic/bitops/instrumented-atomic.h | 100 +++++++
> .../asm-generic/bitops/instrumented-lock.h | 81 ++++++
> .../bitops/instrumented-non-atomic.h | 114 ++++++++
> 7 files changed, 317 insertions(+), 266 deletions(-)
> delete mode 100644 include/asm-generic/bitops-instrumented.h
> create mode 100644 include/asm-generic/bitops/instrumented-atomic.h
> create mode 100644 include/asm-generic/bitops/instrumented-lock.h
> create mode 100644 include/asm-generic/bitops/instrumented-non-atomic.h
>
> diff --git a/Documentation/core-api/kernel-api.rst b/Documentation/core-api/kernel-api.rst
> index 08af5caf036d..2e21248277e3 100644
> --- a/Documentation/core-api/kernel-api.rst
> +++ b/Documentation/core-api/kernel-api.rst
> @@ -54,7 +54,22 @@ The Linux kernel provides more basic utility functions.
> Bit Operations
> --------------
>
> -.. kernel-doc:: include/asm-generic/bitops-instrumented.h
> +Atomic Operations
> +~~~~~~~~~~~~~~~~~
> +
> +.. kernel-doc:: include/asm-generic/bitops/instrumented-atomic.h
> + :internal:
> +
> +Non-atomic Operations
> +~~~~~~~~~~~~~~~~~~~~~
> +
> +.. kernel-doc:: include/asm-generic/bitops/instrumented-non-atomic.h
> + :internal:
> +
> +Locking Operations
> +~~~~~~~~~~~~~~~~~~
> +
> +.. kernel-doc:: include/asm-generic/bitops/instrumented-lock.h
> :internal:
>
> Bitmap Operations
> diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h
> index b8833ac983fa..0ceb12593a68 100644
> --- a/arch/s390/include/asm/bitops.h
> +++ b/arch/s390/include/asm/bitops.h
> @@ -241,7 +241,9 @@ static inline void arch___clear_bit_unlock(unsigned long nr,
> arch___clear_bit(nr, ptr);
> }
>
> -#include <asm-generic/bitops-instrumented.h>
> +#include <asm-generic/bitops/instrumented-atomic.h>
> +#include <asm-generic/bitops/instrumented-non-atomic.h>
> +#include <asm-generic/bitops/instrumented-lock.h>
>
> /*
> * Functions which use MSB0 bit numbering.
> diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
> index ba15d53c1ca7..4a2e2432238f 100644
> --- a/arch/x86/include/asm/bitops.h
> +++ b/arch/x86/include/asm/bitops.h
> @@ -389,7 +389,9 @@ static __always_inline int fls64(__u64 x)
>
> #include <asm-generic/bitops/const_hweight.h>
>
> -#include <asm-generic/bitops-instrumented.h>
> +#include <asm-generic/bitops/instrumented-atomic.h>
> +#include <asm-generic/bitops/instrumented-non-atomic.h>
> +#include <asm-generic/bitops/instrumented-lock.h>
>
> #include <asm-generic/bitops/le.h>
>
> diff --git a/include/asm-generic/bitops-instrumented.h b/include/asm-generic/bitops-instrumented.h
> deleted file mode 100644
> index ddd1c6d9d8db..000000000000
> --- a/include/asm-generic/bitops-instrumented.h
> +++ /dev/null
> @@ -1,263 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -
> -/*
> - * This file provides wrappers with sanitizer instrumentation for bit
> - * operations.
> - *
> - * To use this functionality, an arch's bitops.h file needs to define each of
> - * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
> - * arch___set_bit(), etc.).
> - */
> -#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_H
> -#define _ASM_GENERIC_BITOPS_INSTRUMENTED_H
> -
> -#include <linux/kasan-checks.h>
> -
> -/**
> - * set_bit - Atomically set a bit in memory
> - * @nr: the bit to set
> - * @addr: the address to start counting from
> - *
> - * This is a relaxed atomic operation (no implied memory barriers).
> - *
> - * Note that @nr may be almost arbitrarily large; this function is not
> - * restricted to acting on a single-word quantity.
> - */
> -static inline void set_bit(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - arch_set_bit(nr, addr);
> -}
> -
> -/**
> - * __set_bit - Set a bit in memory
> - * @nr: the bit to set
> - * @addr: the address to start counting from
> - *
> - * Unlike set_bit(), this function is non-atomic. If it is called on the same
> - * region of memory concurrently, the effect may be that only one operation
> - * succeeds.
> - */
> -static inline void __set_bit(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - arch___set_bit(nr, addr);
> -}
> -
> -/**
> - * clear_bit - Clears a bit in memory
> - * @nr: Bit to clear
> - * @addr: Address to start counting from
> - *
> - * This is a relaxed atomic operation (no implied memory barriers).
> - */
> -static inline void clear_bit(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - arch_clear_bit(nr, addr);
> -}
> -
> -/**
> - * __clear_bit - Clears a bit in memory
> - * @nr: the bit to clear
> - * @addr: the address to start counting from
> - *
> - * Unlike clear_bit(), this function is non-atomic. If it is called on the same
> - * region of memory concurrently, the effect may be that only one operation
> - * succeeds.
> - */
> -static inline void __clear_bit(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - arch___clear_bit(nr, addr);
> -}
> -
> -/**
> - * clear_bit_unlock - Clear a bit in memory, for unlock
> - * @nr: the bit to set
> - * @addr: the address to start counting from
> - *
> - * This operation is atomic and provides release barrier semantics.
> - */
> -static inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - arch_clear_bit_unlock(nr, addr);
> -}
> -
> -/**
> - * __clear_bit_unlock - Clears a bit in memory
> - * @nr: Bit to clear
> - * @addr: Address to start counting from
> - *
> - * This is a non-atomic operation but implies a release barrier before the
> - * memory operation. It can be used for an unlock if no other CPUs can
> - * concurrently modify other bits in the word.
> - */
> -static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - arch___clear_bit_unlock(nr, addr);
> -}
> -
> -/**
> - * change_bit - Toggle a bit in memory
> - * @nr: Bit to change
> - * @addr: Address to start counting from
> - *
> - * This is a relaxed atomic operation (no implied memory barriers).
> - *
> - * Note that @nr may be almost arbitrarily large; this function is not
> - * restricted to acting on a single-word quantity.
> - */
> -static inline void change_bit(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - arch_change_bit(nr, addr);
> -}
> -
> -/**
> - * __change_bit - Toggle a bit in memory
> - * @nr: the bit to change
> - * @addr: the address to start counting from
> - *
> - * Unlike change_bit(), this function is non-atomic. If it is called on the same
> - * region of memory concurrently, the effect may be that only one operation
> - * succeeds.
> - */
> -static inline void __change_bit(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - arch___change_bit(nr, addr);
> -}
> -
> -/**
> - * test_and_set_bit - Set a bit and return its old value
> - * @nr: Bit to set
> - * @addr: Address to count from
> - *
> - * This is an atomic fully-ordered operation (implied full memory barrier).
> - */
> -static inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - return arch_test_and_set_bit(nr, addr);
> -}
> -
> -/**
> - * __test_and_set_bit - Set a bit and return its old value
> - * @nr: Bit to set
> - * @addr: Address to count from
> - *
> - * This operation is non-atomic. If two instances of this operation race, one
> - * can appear to succeed but actually fail.
> - */
> -static inline bool __test_and_set_bit(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - return arch___test_and_set_bit(nr, addr);
> -}
> -
> -/**
> - * test_and_set_bit_lock - Set a bit and return its old value, for lock
> - * @nr: Bit to set
> - * @addr: Address to count from
> - *
> - * This operation is atomic and provides acquire barrier semantics if
> - * the returned value is 0.
> - * It can be used to implement bit locks.
> - */
> -static inline bool test_and_set_bit_lock(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - return arch_test_and_set_bit_lock(nr, addr);
> -}
> -
> -/**
> - * test_and_clear_bit - Clear a bit and return its old value
> - * @nr: Bit to clear
> - * @addr: Address to count from
> - *
> - * This is an atomic fully-ordered operation (implied full memory barrier).
> - */
> -static inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - return arch_test_and_clear_bit(nr, addr);
> -}
> -
> -/**
> - * __test_and_clear_bit - Clear a bit and return its old value
> - * @nr: Bit to clear
> - * @addr: Address to count from
> - *
> - * This operation is non-atomic. If two instances of this operation race, one
> - * can appear to succeed but actually fail.
> - */
> -static inline bool __test_and_clear_bit(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - return arch___test_and_clear_bit(nr, addr);
> -}
> -
> -/**
> - * test_and_change_bit - Change a bit and return its old value
> - * @nr: Bit to change
> - * @addr: Address to count from
> - *
> - * This is an atomic fully-ordered operation (implied full memory barrier).
> - */
> -static inline bool test_and_change_bit(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - return arch_test_and_change_bit(nr, addr);
> -}
> -
> -/**
> - * __test_and_change_bit - Change a bit and return its old value
> - * @nr: Bit to change
> - * @addr: Address to count from
> - *
> - * This operation is non-atomic. If two instances of this operation race, one
> - * can appear to succeed but actually fail.
> - */
> -static inline bool __test_and_change_bit(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - return arch___test_and_change_bit(nr, addr);
> -}
> -
> -/**
> - * test_bit - Determine whether a bit is set
> - * @nr: bit number to test
> - * @addr: Address to start counting from
> - */
> -static inline bool test_bit(long nr, const volatile unsigned long *addr)
> -{
> - kasan_check_read(addr + BIT_WORD(nr), sizeof(long));
> - return arch_test_bit(nr, addr);
> -}
> -
> -#if defined(arch_clear_bit_unlock_is_negative_byte)
> -/**
> - * clear_bit_unlock_is_negative_byte - Clear a bit in memory and test if bottom
> - * byte is negative, for unlock.
> - * @nr: the bit to clear
> - * @addr: the address to start counting from
> - *
> - * This operation is atomic and provides release barrier semantics.
> - *
> - * This is a bit of a one-trick-pony for the filemap code, which clears
> - * PG_locked and tests PG_waiters,
> - */
> -static inline bool
> -clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr)
> -{
> - kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> - return arch_clear_bit_unlock_is_negative_byte(nr, addr);
> -}
> -/* Let everybody know we have it. */
> -#define clear_bit_unlock_is_negative_byte clear_bit_unlock_is_negative_byte
> -#endif
> -
> -#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_H */
> diff --git a/include/asm-generic/bitops/instrumented-atomic.h b/include/asm-generic/bitops/instrumented-atomic.h
> new file mode 100644
> index 000000000000..18ce3c9e8eec
> --- /dev/null
> +++ b/include/asm-generic/bitops/instrumented-atomic.h
> @@ -0,0 +1,100 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +/*
> + * This file provides wrappers with sanitizer instrumentation for atomic bit
> + * operations.
> + *
> + * To use this functionality, an arch's bitops.h file needs to define each of
> + * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
> + * arch___set_bit(), etc.).
> + */
> +#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_ATOMIC_H
> +#define _ASM_GENERIC_BITOPS_INSTRUMENTED_ATOMIC_H
> +
> +#include <linux/kasan-checks.h>
> +
> +/**
> + * set_bit - Atomically set a bit in memory
> + * @nr: the bit to set
> + * @addr: the address to start counting from
> + *
> + * This is a relaxed atomic operation (no implied memory barriers).
> + *
> + * Note that @nr may be almost arbitrarily large; this function is not
> + * restricted to acting on a single-word quantity.
> + */
> +static inline void set_bit(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + arch_set_bit(nr, addr);
> +}
> +
> +/**
> + * clear_bit - Clears a bit in memory
> + * @nr: Bit to clear
> + * @addr: Address to start counting from
> + *
> + * This is a relaxed atomic operation (no implied memory barriers).
> + */
> +static inline void clear_bit(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + arch_clear_bit(nr, addr);
> +}
> +
> +/**
> + * change_bit - Toggle a bit in memory
> + * @nr: Bit to change
> + * @addr: Address to start counting from
> + *
> + * This is a relaxed atomic operation (no implied memory barriers).
> + *
> + * Note that @nr may be almost arbitrarily large; this function is not
> + * restricted to acting on a single-word quantity.
> + */
> +static inline void change_bit(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + arch_change_bit(nr, addr);
> +}
> +
> +/**
> + * test_and_set_bit - Set a bit and return its old value
> + * @nr: Bit to set
> + * @addr: Address to count from
> + *
> + * This is an atomic fully-ordered operation (implied full memory barrier).
> + */
> +static inline bool test_and_set_bit(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + return arch_test_and_set_bit(nr, addr);
> +}
> +
> +/**
> + * test_and_clear_bit - Clear a bit and return its old value
> + * @nr: Bit to clear
> + * @addr: Address to count from
> + *
> + * This is an atomic fully-ordered operation (implied full memory barrier).
> + */
> +static inline bool test_and_clear_bit(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + return arch_test_and_clear_bit(nr, addr);
> +}
> +
> +/**
> + * test_and_change_bit - Change a bit and return its old value
> + * @nr: Bit to change
> + * @addr: Address to count from
> + *
> + * This is an atomic fully-ordered operation (implied full memory barrier).
> + */
> +static inline bool test_and_change_bit(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + return arch_test_and_change_bit(nr, addr);
> +}
> +
> +#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H */
> diff --git a/include/asm-generic/bitops/instrumented-lock.h b/include/asm-generic/bitops/instrumented-lock.h
> new file mode 100644
> index 000000000000..ec53fdeea9ec
> --- /dev/null
> +++ b/include/asm-generic/bitops/instrumented-lock.h
> @@ -0,0 +1,81 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +/*
> + * This file provides wrappers with sanitizer instrumentation for bit
> + * locking operations.
> + *
> + * To use this functionality, an arch's bitops.h file needs to define each of
> + * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
> + * arch___set_bit(), etc.).
> + */
> +#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H
> +#define _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H
> +
> +#include <linux/kasan-checks.h>
> +
> +/**
> + * clear_bit_unlock - Clear a bit in memory, for unlock
> + * @nr: the bit to set
> + * @addr: the address to start counting from
> + *
> + * This operation is atomic and provides release barrier semantics.
> + */
> +static inline void clear_bit_unlock(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + arch_clear_bit_unlock(nr, addr);
> +}
> +
> +/**
> + * __clear_bit_unlock - Clears a bit in memory
> + * @nr: Bit to clear
> + * @addr: Address to start counting from
> + *
> + * This is a non-atomic operation but implies a release barrier before the
> + * memory operation. It can be used for an unlock if no other CPUs can
> + * concurrently modify other bits in the word.
> + */
> +static inline void __clear_bit_unlock(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + arch___clear_bit_unlock(nr, addr);
> +}
> +
> +/**
> + * test_and_set_bit_lock - Set a bit and return its old value, for lock
> + * @nr: Bit to set
> + * @addr: Address to count from
> + *
> + * This operation is atomic and provides acquire barrier semantics if
> + * the returned value is 0.
> + * It can be used to implement bit locks.
> + */
> +static inline bool test_and_set_bit_lock(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + return arch_test_and_set_bit_lock(nr, addr);
> +}
> +
> +#if defined(arch_clear_bit_unlock_is_negative_byte)
> +/**
> + * clear_bit_unlock_is_negative_byte - Clear a bit in memory and test if bottom
> + * byte is negative, for unlock.
> + * @nr: the bit to clear
> + * @addr: the address to start counting from
> + *
> + * This operation is atomic and provides release barrier semantics.
> + *
> + * This is a bit of a one-trick-pony for the filemap code, which clears
> + * PG_locked and tests PG_waiters,
> + */
> +static inline bool
> +clear_bit_unlock_is_negative_byte(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + return arch_clear_bit_unlock_is_negative_byte(nr, addr);
> +}
> +/* Let everybody know we have it. */
> +#define clear_bit_unlock_is_negative_byte clear_bit_unlock_is_negative_byte
> +#endif
> +
> +#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_LOCK_H */
> diff --git a/include/asm-generic/bitops/instrumented-non-atomic.h b/include/asm-generic/bitops/instrumented-non-atomic.h
> new file mode 100644
> index 000000000000..95ff28d128a1
> --- /dev/null
> +++ b/include/asm-generic/bitops/instrumented-non-atomic.h
> @@ -0,0 +1,114 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +/*
> + * This file provides wrappers with sanitizer instrumentation for non-atomic
> + * bit operations.
> + *
> + * To use this functionality, an arch's bitops.h file needs to define each of
> + * the below bit operations with an arch_ prefix (e.g. arch_set_bit(),
> + * arch___set_bit(), etc.).
> + */
> +#ifndef _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
> +#define _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H
> +
> +#include <linux/kasan-checks.h>
> +
> +/**
> + * __set_bit - Set a bit in memory
> + * @nr: the bit to set
> + * @addr: the address to start counting from
> + *
> + * Unlike set_bit(), this function is non-atomic. If it is called on the same
> + * region of memory concurrently, the effect may be that only one operation
> + * succeeds.
> + */
> +static inline void __set_bit(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + arch___set_bit(nr, addr);
> +}
> +
> +/**
> + * __clear_bit - Clears a bit in memory
> + * @nr: the bit to clear
> + * @addr: the address to start counting from
> + *
> + * Unlike clear_bit(), this function is non-atomic. If it is called on the same
> + * region of memory concurrently, the effect may be that only one operation
> + * succeeds.
> + */
> +static inline void __clear_bit(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + arch___clear_bit(nr, addr);
> +}
> +
> +/**
> + * __change_bit - Toggle a bit in memory
> + * @nr: the bit to change
> + * @addr: the address to start counting from
> + *
> + * Unlike change_bit(), this function is non-atomic. If it is called on the same
> + * region of memory concurrently, the effect may be that only one operation
> + * succeeds.
> + */
> +static inline void __change_bit(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + arch___change_bit(nr, addr);
> +}
> +
> +/**
> + * __test_and_set_bit - Set a bit and return its old value
> + * @nr: Bit to set
> + * @addr: Address to count from
> + *
> + * This operation is non-atomic. If two instances of this operation race, one
> + * can appear to succeed but actually fail.
> + */
> +static inline bool __test_and_set_bit(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + return arch___test_and_set_bit(nr, addr);
> +}
> +
> +/**
> + * __test_and_clear_bit - Clear a bit and return its old value
> + * @nr: Bit to clear
> + * @addr: Address to count from
> + *
> + * This operation is non-atomic. If two instances of this operation race, one
> + * can appear to succeed but actually fail.
> + */
> +static inline bool __test_and_clear_bit(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + return arch___test_and_clear_bit(nr, addr);
> +}
> +
> +/**
> + * __test_and_change_bit - Change a bit and return its old value
> + * @nr: Bit to change
> + * @addr: Address to count from
> + *
> + * This operation is non-atomic. If two instances of this operation race, one
> + * can appear to succeed but actually fail.
> + */
> +static inline bool __test_and_change_bit(long nr, volatile unsigned long *addr)
> +{
> + kasan_check_write(addr + BIT_WORD(nr), sizeof(long));
> + return arch___test_and_change_bit(nr, addr);
> +}
> +
> +/**
> + * test_bit - Determine whether a bit is set
> + * @nr: bit number to test
> + * @addr: Address to start counting from
> + */
> +static inline bool test_bit(long nr, const volatile unsigned long *addr)
> +{
> + kasan_check_read(addr + BIT_WORD(nr), sizeof(long));
> + return arch_test_bit(nr, addr);
> +}
> +
> +#endif /* _ASM_GENERIC_BITOPS_INSTRUMENTED_NON_ATOMIC_H */
> --
> 2.20.1
^ permalink raw reply
* Re: [PATCH v5 3/5] powerpc/64: make buildable without CONFIG_COMPAT
From: Christophe Leroy @ 2019-08-30 6:35 UTC (permalink / raw)
To: Michal Suchanek, linuxppc-dev
Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
Breno Leitao, Michael Neuling, Nicolai Stange, Geert Uytterhoeven,
Allison Randal, Firoz Khan, Joel Stanley, Arnd Bergmann,
Nicholas Piggin, Thomas Gleixner, Christian Brauner,
Greg Kroah-Hartman, linux-kernel, Eric W. Biederman,
Andrew Donnellan, Hari Bathini
In-Reply-To: <90594004804c6a9b690b69bdf0e5c4d6c880c5f4.1567117050.git.msuchanek@suse.de>
On 08/29/2019 10:28 PM, Michal Suchanek wrote:
> There are numerous references to 32bit functions in generic and 64bit
> code so ifdef them out.
>
> Signed-off-by: Michal Suchanek <msuchanek@suse.de>
> ---
> v2:
> - fix 32bit ifdef condition in signal.c
> - simplify the compat ifdef condition in vdso.c - 64bit is redundant
> - simplify the compat ifdef condition in callchain.c - 64bit is redundant
> v3:
> - use IS_ENABLED and maybe_unused where possible
> - do not ifdef declarations
> - clean up Makefile
> v4:
> - further makefile cleanup
> - simplify is_32bit_task conditions
> - avoid ifdef in condition by using return
> v5:
> - avoid unreachable code on 32bit
> - make is_current_64bit constant on !COMPAT
> - add stub perf_callchain_user_32 to avoid some ifdefs
> ---
> arch/powerpc/include/asm/thread_info.h | 4 ++--
> arch/powerpc/kernel/Makefile | 7 +++----
> arch/powerpc/kernel/entry_64.S | 2 ++
> arch/powerpc/kernel/signal.c | 3 +--
> arch/powerpc/kernel/syscall_64.c | 6 ++----
> arch/powerpc/kernel/vdso.c | 5 ++---
> arch/powerpc/perf/callchain.c | 13 +++++++++++--
> 7 files changed, 23 insertions(+), 17 deletions(-)
>
[...]
> diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
> index c84bbd4298a0..881be5c4e9bb 100644
> --- a/arch/powerpc/perf/callchain.c
> +++ b/arch/powerpc/perf/callchain.c
> @@ -15,7 +15,7 @@
> #include <asm/sigcontext.h>
> #include <asm/ucontext.h>
> #include <asm/vdso.h>
> -#ifdef CONFIG_PPC64
> +#ifdef CONFIG_COMPAT
> #include "../kernel/ppc32.h"
> #endif
> #include <asm/pte-walk.h>
> @@ -291,7 +291,8 @@ static inline int current_is_64bit(void)
> * interrupt stack, and the thread flags don't get copied over
> * from the thread_info on the main stack to the interrupt stack.
> */
> - return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
> + return !IS_ENABLED(CONFIG_COMPAT) ||
> + !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
> }
>
> #else /* CONFIG_PPC64 */
> @@ -341,6 +342,7 @@ static inline int valid_user_sp(unsigned long sp, int is_64)
>
> #endif /* CONFIG_PPC64 */
>
> +#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
> /*
> * Layout for non-RT signal frames
> */
> @@ -482,6 +484,13 @@ static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> sp = next_sp;
> }
> }
> +#else /* 32bit */
> +static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> + struct pt_regs *regs)
> +{
> + (void)&read_user_stack_32; /* unused if !COMPAT */
That looks pretty much like a hack.
See possible alternative below.
> +}
> +#endif /* 32bit */
>
> void
> perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
>
---
arch/powerpc/perf/callchain.c | 62 +++++++++++++++++++------------------------
1 file changed, 27 insertions(+), 35 deletions(-)
diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
index 881be5c4e9bb..1b169b32776a 100644
--- a/arch/powerpc/perf/callchain.c
+++ b/arch/powerpc/perf/callchain.c
@@ -165,22 +165,6 @@ static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
return read_user_stack_slow(ptr, ret, 8);
}
-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
-{
- if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
- ((unsigned long)ptr & 3))
- return -EFAULT;
-
- pagefault_disable();
- if (!__get_user_inatomic(*ret, ptr)) {
- pagefault_enable();
- return 0;
- }
- pagefault_enable();
-
- return read_user_stack_slow(ptr, ret, 4);
-}
-
static inline int valid_user_sp(unsigned long sp, int is_64)
{
if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x100000000UL) - 32)
@@ -296,25 +280,10 @@ static inline int current_is_64bit(void)
}
#else /* CONFIG_PPC64 */
-/*
- * On 32-bit we just access the address and let hash_page create a
- * HPTE if necessary, so there is no need to fall back to reading
- * the page tables. Since this is called at interrupt level,
- * do_page_fault() won't treat a DSI as a page fault.
- */
-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
-{
- int rc;
-
- if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
- ((unsigned long)ptr & 3))
- return -EFAULT;
- pagefault_disable();
- rc = __get_user_inatomic(*ret, ptr);
- pagefault_enable();
-
- return rc;
+static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
+{
+ return 0;
}
static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
@@ -344,6 +313,30 @@ static inline int valid_user_sp(unsigned long sp, int is_64)
#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
/*
+ * On 32-bit we just access the address and let hash_page create a
+ * HPTE if necessary, so there is no need to fall back to reading
+ * the page tables. Since this is called at interrupt level,
+ * do_page_fault() won't treat a DSI as a page fault.
+ */
+static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
+{
+ int rc;
+
+ if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
+ ((unsigned long)ptr & 3))
+ return -EFAULT;
+
+ pagefault_disable();
+ rc = __get_user_inatomic(*ret, ptr);
+ pagefault_enable();
+
+ if (IS_ENABLED(CONFIG_PPC32) || !rc)
+ return rc;
+
+ return read_user_stack_slow(ptr, ret, 4);
+}
+
+/*
* Layout for non-RT signal frames
*/
struct signal_frame_32 {
@@ -488,7 +481,6 @@ static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
struct pt_regs *regs)
{
- (void)&read_user_stack_32; /* unused if !COMPAT */
}
#endif /* 32bit */
--
2.13.3
^ permalink raw reply related
* Re: [PATCH v5 5/5] powerpc/perf: split callchain.c by bitness
From: Christophe Leroy @ 2019-08-30 6:35 UTC (permalink / raw)
To: linuxppc-dev, Michal Suchanek
Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
Breno Leitao, Michael Neuling, Nicolai Stange, Geert Uytterhoeven,
Allison Randal, Firoz Khan, Joel Stanley, Arnd Bergmann,
Nicholas Piggin, Thomas Gleixner, Christian Brauner,
Greg Kroah-Hartman, linux-kernel, Eric W. Biederman,
Andrew Donnellan, Hari Bathini
In-Reply-To: <c77eec3d99fd0251edf725a3d9e1b79f396eba6e.1567117050.git.msuchanek@suse.de>
On 08/29/2019 10:28 PM, Michal Suchanek wrote:
> Building callchain.c with !COMPAT proved quite ugly with all the
> defines. Splitting out the 32bit and 64bit parts looks better.
>
> Also rewrite current_is_64bit as common function. No other code change
> intended.
Nice result.
Could look even better by merging both read_user_stack_32(), see below.
Also a possible cosmetic change to Makefile.
---
arch/powerpc/perf/Makefile | 7 ++---
arch/powerpc/perf/callchain_32.c | 65 ++++++++++++++++------------------------
2 files changed, 29 insertions(+), 43 deletions(-)
diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index e9f3202251d0..53d614e98537 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -1,9 +1,8 @@
# SPDX-License-Identifier: GPL-2.0
-obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o
-ifdef CONFIG_PERF_EVENTS
-obj-y += callchain_$(BITS).o
-obj-$(CONFIG_COMPAT) += callchain_32.o
+obj-$(CONFIG_PERF_EVENTS) += callchain.o callchain_$(BITS).o perf_regs.o
+ifdef CONFIG_COMPAT
+obj-$(CONFIG_PERF_EVENTS) += callchain_32.o
endif
obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o bhrb.o
diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c
index 0bd4484eddaa..17c43ae03084 100644
--- a/arch/powerpc/perf/callchain_32.c
+++ b/arch/powerpc/perf/callchain_32.c
@@ -15,50 +15,13 @@
#include <asm/sigcontext.h>
#include <asm/ucontext.h>
#include <asm/vdso.h>
-#ifdef CONFIG_PPC64
-#include "../kernel/ppc32.h"
-#endif
#include <asm/pte-walk.h>
#include "callchain.h"
#ifdef CONFIG_PPC64
-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
-{
- if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
- ((unsigned long)ptr & 3))
- return -EFAULT;
-
- pagefault_disable();
- if (!__get_user_inatomic(*ret, ptr)) {
- pagefault_enable();
- return 0;
- }
- pagefault_enable();
-
- return read_user_stack_slow(ptr, ret, 4);
-}
-#else /* CONFIG_PPC64 */
-/*
- * On 32-bit we just access the address and let hash_page create a
- * HPTE if necessary, so there is no need to fall back to reading
- * the page tables. Since this is called at interrupt level,
- * do_page_fault() won't treat a DSI as a page fault.
- */
-static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
-{
- int rc;
-
- if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
- ((unsigned long)ptr & 3))
- return -EFAULT;
-
- pagefault_disable();
- rc = __get_user_inatomic(*ret, ptr);
- pagefault_enable();
-
- return rc;
-}
+#include "../kernel/ppc32.h"
+#else
#define __SIGNAL_FRAMESIZE32 __SIGNAL_FRAMESIZE
#define sigcontext32 sigcontext
@@ -95,6 +58,30 @@ struct rt_signal_frame_32 {
int abigap[56];
};
+/*
+ * On 32-bit we just access the address and let hash_page create a
+ * HPTE if necessary, so there is no need to fall back to reading
+ * the page tables. Since this is called at interrupt level,
+ * do_page_fault() won't treat a DSI as a page fault.
+ */
+static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
+{
+ int rc;
+
+ if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
+ ((unsigned long)ptr & 3))
+ return -EFAULT;
+
+ pagefault_disable();
+ rc = __get_user_inatomic(*ret, ptr);
+ pagefault_enable();
+
+ if (IS_ENABLED(CONFIG_PPC32) || !rc)
+ return rc;
+
+ return read_user_stack_slow(ptr, ret, 4);
+}
+
static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
{
if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))
--
2.13.3
^ permalink raw reply related
* Re: [PATCH v5 5/5] powerpc/perf: split callchain.c by bitness
From: Michal Suchánek @ 2019-08-30 6:42 UTC (permalink / raw)
To: Christophe Leroy
Cc: David Hildenbrand, Heiko Carstens, David Howells, Paul Mackerras,
Breno Leitao, Michael Neuling, Nicolai Stange, Geert Uytterhoeven,
Allison Randal, Firoz Khan, Joel Stanley, Arnd Bergmann,
Nicholas Piggin, Thomas Gleixner, Christian Brauner,
Greg Kroah-Hartman, linux-kernel, Eric W. Biederman,
Andrew Donnellan, Hari Bathini, linuxppc-dev
In-Reply-To: <4d996b0a225ca5b7d287ae46825d7da4a1d6e509.1567146554.git.christophe.leroy@c-s.fr>
On Fri, 30 Aug 2019 06:35:11 +0000 (UTC)
Christophe Leroy <christophe.leroy@c-s.fr> wrote:
> On 08/29/2019 10:28 PM, Michal Suchanek wrote:
> > Building callchain.c with !COMPAT proved quite ugly with all the
> > defines. Splitting out the 32bit and 64bit parts looks better.
> >
> > Also rewrite current_is_64bit as common function. No other code change
> > intended.
>
> Nice result.
>
> Could look even better by merging both read_user_stack_32(), see below.
>
> Also a possible cosmetic change to Makefile.
>
> ---
> arch/powerpc/perf/Makefile | 7 ++---
> arch/powerpc/perf/callchain_32.c | 65 ++++++++++++++++------------------------
> 2 files changed, 29 insertions(+), 43 deletions(-)
>
> diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
> index e9f3202251d0..53d614e98537 100644
> --- a/arch/powerpc/perf/Makefile
> +++ b/arch/powerpc/perf/Makefile
> @@ -1,9 +1,8 @@
> # SPDX-License-Identifier: GPL-2.0
>
> -obj-$(CONFIG_PERF_EVENTS) += callchain.o perf_regs.o
> -ifdef CONFIG_PERF_EVENTS
> -obj-y += callchain_$(BITS).o
> -obj-$(CONFIG_COMPAT) += callchain_32.o
> +obj-$(CONFIG_PERF_EVENTS) += callchain.o callchain_$(BITS).o perf_regs.o
> +ifdef CONFIG_COMPAT
> +obj-$(CONFIG_PERF_EVENTS) += callchain_32.o
> endif
>
That looks good.
> obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o bhrb.o
> diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c
> index 0bd4484eddaa..17c43ae03084 100644
> --- a/arch/powerpc/perf/callchain_32.c
> +++ b/arch/powerpc/perf/callchain_32.c
> @@ -15,50 +15,13 @@
> #include <asm/sigcontext.h>
> #include <asm/ucontext.h>
> #include <asm/vdso.h>
> -#ifdef CONFIG_PPC64
> -#include "../kernel/ppc32.h"
> -#endif
> #include <asm/pte-walk.h>
>
> #include "callchain.h"
>
> #ifdef CONFIG_PPC64
> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> -{
> - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> - ((unsigned long)ptr & 3))
> - return -EFAULT;
> -
> - pagefault_disable();
> - if (!__get_user_inatomic(*ret, ptr)) {
> - pagefault_enable();
> - return 0;
> - }
> - pagefault_enable();
> -
> - return read_user_stack_slow(ptr, ret, 4);
> -}
> -#else /* CONFIG_PPC64 */
> -/*
> - * On 32-bit we just access the address and let hash_page create a
> - * HPTE if necessary, so there is no need to fall back to reading
> - * the page tables. Since this is called at interrupt level,
> - * do_page_fault() won't treat a DSI as a page fault.
> - */
> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> -{
> - int rc;
> -
> - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> - ((unsigned long)ptr & 3))
> - return -EFAULT;
> -
> - pagefault_disable();
> - rc = __get_user_inatomic(*ret, ptr);
> - pagefault_enable();
> -
> - return rc;
> -}
> +#include "../kernel/ppc32.h"
> +#else
>
> #define __SIGNAL_FRAMESIZE32 __SIGNAL_FRAMESIZE
> #define sigcontext32 sigcontext
> @@ -95,6 +58,30 @@ struct rt_signal_frame_32 {
> int abigap[56];
> };
>
> +/*
> + * On 32-bit we just access the address and let hash_page create a
> + * HPTE if necessary, so there is no need to fall back to reading
> + * the page tables. Since this is called at interrupt level,
> + * do_page_fault() won't treat a DSI as a page fault.
> + */
> +static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> +{
> + int rc;
> +
> + if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> + ((unsigned long)ptr & 3))
> + return -EFAULT;
> +
> + pagefault_disable();
> + rc = __get_user_inatomic(*ret, ptr);
> + pagefault_enable();
> +
> + if (IS_ENABLED(CONFIG_PPC32) || !rc)
> + return rc;
> +
> + return read_user_stack_slow(ptr, ret, 4);
> +}
> +
> static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
> {
> if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))
I will leave consolidating this function to somebody who knows what the
desired semantic is. With a short ifdef section at the top of the file
it is a low-hanging fruit.
Thanks
Michal
^ permalink raw reply
* Oops (request_key_auth_describe) while running cve-2016-7042 from LTP
From: Sachin Sant @ 2019-08-30 6:48 UTC (permalink / raw)
To: linux-kernel; +Cc: dhowells, linuxppc-dev, keyrings
While running LTP tests (specifically cve-2016-7042) against 5.3-rc6
(commit 4a64489cf8) on a POWER9 LPAR, following problem is seen
[ 3373.814425] FS-Cache: Netfs 'nfs' registered for caching
[ 7695.250230] Clock: inserting leap second 23:59:60 UTC
[ 8074.351033] BUG: Kernel NULL pointer dereference at 0x00000038
[ 8074.351046] Faulting instruction address: 0xc0000000004ddf30
[ 8074.351052] Oops: Kernel access of bad area, sig: 11 [#1]
[ 8074.351056] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
[ 8074.351067] Dumping ftrace buffer:
[ 8074.351081] (ftrace buffer empty)
[ 8074.351085] Modules linked in: nfsv3 nfs_acl nfs lockd grace fscache sctp tun brd vfat fat fuse xfs overlay loop iscsi_target_mod target_core_mod macsec tcp_diag udp_diag inet_diag unix_diag af_packet_diag netlink_diag binfmt_misc bridge stp llc ip6t_rpfilter ipt_REJECT nf_reject_ipv4 ip6t_REJECT nf_reject_ipv6 xt_conntrack ip_set nfnetlink ebtable_nat ebtable_broute ip6table_nat ip6table_mangle ip6table_raw iptable_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 libcrc32c iptable_mangle iptable_raw ebtable_filter ebtables ip6table_filter ip6_tables iptable_filter sunrpc uio_pdrv_genirq pseries_rng sg uio ip_tables ext4 mbcache jbd2 sr_mod cdrom sd_mod ibmvscsi ibmveth scsi_transport_srp dm_mirror dm_region_hash dm_log dm_mod [last unloaded: dummy_del_mod]
[ 8074.351153] CPU: 10 PID: 8314 Comm: cve-2016-7042 Tainted: G O 5.3.0-rc6-autotest #1
[ 8074.351158] NIP: c0000000004ddf30 LR: c0000000004ddef4 CTR: c0000000004ddea0
[ 8074.351164] REGS: c0000000e74fb800 TRAP: 0300 Tainted: G O (5.3.0-rc6-autotest)
[ 8074.351170] MSR: 8000000000009033 <SF,EE,ME,IR,DR,RI,LE> CR: 88002482 XER: 00000000
[ 8074.351177] CFAR: c00000000000dfc4 DAR: 0000000000000038 DSISR: 40000000 IRQMASK: 0
[ 8074.351177] GPR00: c0000000004ddef4 c0000000e74fba90 c0000000013cc200 c0000008b0d7039b
[ 8074.351177] GPR04: c0000008b0dabe3e 0000000000000007 00090a0200000904 c0000008b0d80000
[ 8074.351177] GPR08: 00000000000003a2 0000000000000001 000000000000039b c000000000d03ac0
[ 8074.351177] GPR12: c0000000004ddea0 c00000001ec5dc00 0000000000000000 0000000000000000
[ 8074.351177] GPR16: 0000000000000000 0000000000000002 000000001b010000 0000000000000000
[ 8074.351177] GPR20: 000000003bc24df7 c0000000e74fbc28 0000000000000049 0000000000000052
[ 8074.351177] GPR24: 000000000000002d c0000000ffe30780 c0000008a991d800 000000000000002d
[ 8074.351177] GPR28: 0000000000000069 0000000000000000 c0000000ffe30780 c0000008a991d800
[ 8074.351224] NIP [c0000000004ddf30] request_key_auth_describe+0x90/0xd0
[ 8074.351230] LR [c0000000004ddef4] request_key_auth_describe+0x54/0xd0
[ 8074.351233] Call Trace:
[ 8074.351237] [c0000000e74fba90] [c0000000004ddef4] request_key_auth_describe+0x54/0xd0 (unreliable)
[ 8074.351244] [c0000000e74fbb10] [c0000000004df718] proc_keys_show+0x308/0x4c0
[ 8074.351250] [c0000000e74fbcc0] [c000000000404950] seq_read+0x3d0/0x540
[ 8074.351255] [c0000000e74fbd40] [c0000000004865e0] proc_reg_read+0x90/0x110
[ 8074.351261] [c0000000e74fbd70] [c0000000003c901c] __vfs_read+0x3c/0x70
[ 8074.351267] [c0000000e74fbd90] [c0000000003c9104] vfs_read+0xb4/0x1b0
[ 8074.351272] [c0000000e74fbdd0] [c0000000003c95ec] ksys_read+0x7c/0x130
[ 8074.351277] [c0000000e74fbe20] [c00000000000b388] system_call+0x5c/0x70
[ 8074.351281] Instruction dump:
[ 8074.351285] 2b890001 419e002c 38210080 e8010010 eba1ffe8 ebc1fff0 ebe1fff8 7c0803a6
[ 8074.351292] 4e800020 60000000 60000000 60420000 <e8bd003a> e8dd0030 3c82ff93 7fc3f378
[ 8074.351301] ---[ end trace d3304a3a5a0a0ca1 ]—
These CVE tests from LTP were recently added to the automated regression test bucket that
I run against upstream. I can’t tell if this is a regression or a new problem.
Thanks
-Sachin
^ permalink raw reply
* Re: [PATCH v5 5/5] powerpc/perf: split callchain.c by bitness
From: Michal Suchánek @ 2019-08-30 7:12 UTC (permalink / raw)
To: Christophe Leroy
Cc: Michael Neuling, Arnd Bergmann, Nicolai Stange, David Hildenbrand,
Greg Kroah-Hartman, Andrew Donnellan, Heiko Carstens,
linux-kernel, Nicholas Piggin, David Howells, Hari Bathini,
Paul Mackerras, Joel Stanley, Christian Brauner, Firoz Khan,
Breno Leitao, Geert Uytterhoeven, Thomas Gleixner, linuxppc-dev,
Allison Randal, Eric W. Biederman
In-Reply-To: <20190830084225.527f4265@naga>
On Fri, 30 Aug 2019 08:42:25 +0200
Michal Suchánek <msuchanek@suse.de> wrote:
> On Fri, 30 Aug 2019 06:35:11 +0000 (UTC)
> Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
> > On 08/29/2019 10:28 PM, Michal Suchanek wrote:
> > obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o bhrb.o
> > diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c
> > index 0bd4484eddaa..17c43ae03084 100644
> > --- a/arch/powerpc/perf/callchain_32.c
> > +++ b/arch/powerpc/perf/callchain_32.c
> > @@ -15,50 +15,13 @@
> > #include <asm/sigcontext.h>
> > #include <asm/ucontext.h>
> > #include <asm/vdso.h>
> > -#ifdef CONFIG_PPC64
> > -#include "../kernel/ppc32.h"
> > -#endif
> > #include <asm/pte-walk.h>
> >
> > #include "callchain.h"
> >
> > #ifdef CONFIG_PPC64
> > -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> > -{
> > - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> > - ((unsigned long)ptr & 3))
> > - return -EFAULT;
> > -
> > - pagefault_disable();
> > - if (!__get_user_inatomic(*ret, ptr)) {
> > - pagefault_enable();
> > - return 0;
> > - }
> > - pagefault_enable();
> > -
> > - return read_user_stack_slow(ptr, ret, 4);
> > -}
> > -#else /* CONFIG_PPC64 */
> > -/*
> > - * On 32-bit we just access the address and let hash_page create a
> > - * HPTE if necessary, so there is no need to fall back to reading
> > - * the page tables. Since this is called at interrupt level,
> > - * do_page_fault() won't treat a DSI as a page fault.
> > - */
> > -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> > -{
> > - int rc;
> > -
> > - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> > - ((unsigned long)ptr & 3))
> > - return -EFAULT;
> > -
> > - pagefault_disable();
> > - rc = __get_user_inatomic(*ret, ptr);
> > - pagefault_enable();
> > -
> > - return rc;
> > -}
> > +#include "../kernel/ppc32.h"
> > +#else
> >
> > #define __SIGNAL_FRAMESIZE32 __SIGNAL_FRAMESIZE
> > #define sigcontext32 sigcontext
> > @@ -95,6 +58,30 @@ struct rt_signal_frame_32 {
> > int abigap[56];
> > };
> >
> > +/*
> > + * On 32-bit we just access the address and let hash_page create a
> > + * HPTE if necessary, so there is no need to fall back to reading
> > + * the page tables. Since this is called at interrupt level,
> > + * do_page_fault() won't treat a DSI as a page fault.
> > + */
> > +static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> > +{
> > + int rc;
> > +
> > + if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> > + ((unsigned long)ptr & 3))
> > + return -EFAULT;
> > +
> > + pagefault_disable();
> > + rc = __get_user_inatomic(*ret, ptr);
> > + pagefault_enable();
> > +
> > + if (IS_ENABLED(CONFIG_PPC32) || !rc)
> > + return rc;
> > +
> > + return read_user_stack_slow(ptr, ret, 4);
> > +}
> > +
> > static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
> > {
> > if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))
>
> I will leave consolidating this function to somebody who knows what the
> desired semantic is. With a short ifdef section at the top of the file
> it is a low-hanging fruit.
It looks ok if done as a separate patch.
Thanks
Michal
^ permalink raw reply
* Re: [PATCH v5 5/5] powerpc/perf: split callchain.c by bitness
From: Christophe Leroy @ 2019-08-30 7:15 UTC (permalink / raw)
To: Michal Suchánek
Cc: Michael Neuling, Arnd Bergmann, Nicolai Stange, David Hildenbrand,
Greg Kroah-Hartman, Andrew Donnellan, Heiko Carstens,
linux-kernel, Nicholas Piggin, David Howells, Hari Bathini,
Paul Mackerras, Joel Stanley, Christian Brauner, Firoz Khan,
Breno Leitao, Geert Uytterhoeven, Thomas Gleixner, linuxppc-dev,
Allison Randal, Eric W. Biederman
In-Reply-To: <20190830091212.4d1d619f@naga>
Le 30/08/2019 à 09:12, Michal Suchánek a écrit :
> On Fri, 30 Aug 2019 08:42:25 +0200
> Michal Suchánek <msuchanek@suse.de> wrote:
>
>> On Fri, 30 Aug 2019 06:35:11 +0000 (UTC)
>> Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>>
>>> On 08/29/2019 10:28 PM, Michal Suchanek wrote:
>
>>> obj-$(CONFIG_PPC_PERF_CTRS) += core-book3s.o bhrb.o
>>> diff --git a/arch/powerpc/perf/callchain_32.c b/arch/powerpc/perf/callchain_32.c
>>> index 0bd4484eddaa..17c43ae03084 100644
>>> --- a/arch/powerpc/perf/callchain_32.c
>>> +++ b/arch/powerpc/perf/callchain_32.c
>>> @@ -15,50 +15,13 @@
>>> #include <asm/sigcontext.h>
>>> #include <asm/ucontext.h>
>>> #include <asm/vdso.h>
>>> -#ifdef CONFIG_PPC64
>>> -#include "../kernel/ppc32.h"
>>> -#endif
>>> #include <asm/pte-walk.h>
>>>
>>> #include "callchain.h"
>>>
>>> #ifdef CONFIG_PPC64
>>> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
>>> -{
>>> - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
>>> - ((unsigned long)ptr & 3))
>>> - return -EFAULT;
>>> -
>>> - pagefault_disable();
>>> - if (!__get_user_inatomic(*ret, ptr)) {
>>> - pagefault_enable();
>>> - return 0;
>>> - }
>>> - pagefault_enable();
>>> -
>>> - return read_user_stack_slow(ptr, ret, 4);
>>> -}
>>> -#else /* CONFIG_PPC64 */
>>> -/*
>>> - * On 32-bit we just access the address and let hash_page create a
>>> - * HPTE if necessary, so there is no need to fall back to reading
>>> - * the page tables. Since this is called at interrupt level,
>>> - * do_page_fault() won't treat a DSI as a page fault.
>>> - */
>>> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
>>> -{
>>> - int rc;
>>> -
>>> - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
>>> - ((unsigned long)ptr & 3))
>>> - return -EFAULT;
>>> -
>>> - pagefault_disable();
>>> - rc = __get_user_inatomic(*ret, ptr);
>>> - pagefault_enable();
>>> -
>>> - return rc;
>>> -}
>>> +#include "../kernel/ppc32.h"
>>> +#else
>>>
>>> #define __SIGNAL_FRAMESIZE32 __SIGNAL_FRAMESIZE
>>> #define sigcontext32 sigcontext
>>> @@ -95,6 +58,30 @@ struct rt_signal_frame_32 {
>>> int abigap[56];
>>> };
>>>
>>> +/*
>>> + * On 32-bit we just access the address and let hash_page create a
>>> + * HPTE if necessary, so there is no need to fall back to reading
>>> + * the page tables. Since this is called at interrupt level,
>>> + * do_page_fault() won't treat a DSI as a page fault.
>>> + */
>>> +static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
>>> +{
>>> + int rc;
>>> +
>>> + if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
>>> + ((unsigned long)ptr & 3))
>>> + return -EFAULT;
>>> +
>>> + pagefault_disable();
>>> + rc = __get_user_inatomic(*ret, ptr);
>>> + pagefault_enable();
>>> +
>>> + if (IS_ENABLED(CONFIG_PPC32) || !rc)
>>> + return rc;
>>> +
>>> + return read_user_stack_slow(ptr, ret, 4);
>>> +}
>>> +
>>> static int is_sigreturn_32_address(unsigned int nip, unsigned int fp)
>>> {
>>> if (nip == fp + offsetof(struct signal_frame_32, mctx.mc_pad))
>>
>> I will leave consolidating this function to somebody who knows what the
>> desired semantic is. With a short ifdef section at the top of the file
>> it is a low-hanging fruit.
>
> It looks ok if done as a separate patch.
Yes, doing it as a separate patch is good.
And if you do it before patch 3, then you don't need anymore this ugly
hack to hide read_user_stack_32()
Christphe
>
> Thanks
>
> Michal
>
^ permalink raw reply
* Re: [PATCH] powerpc/mm: tell if a bad page fault on data is read or write.
From: Christophe Leroy @ 2019-08-30 7:41 UTC (permalink / raw)
To: Michael Ellerman, Benjamin Herrenschmidt, Paul Mackerras
Cc: linuxppc-dev, linux-kernel
In-Reply-To: <87o908tbgx.fsf@mpe.ellerman.id.au>
Le 29/08/2019 à 14:14, Michael Ellerman a écrit :
> Christophe Leroy <christophe.leroy@c-s.fr> writes:
>> DSISR has a bit to tell if the fault is due to a read or a write.
>
> Except some CPUs don't have a DSISR?
>
> Which is why we have page_fault_is_write() that's used in
> __do_page_fault().
And that's why I'm also using page_fault_is_write() in my patch.
>
> Or is that old cruft?
>
> I see eg. in head_40x.S we pass r5=0 for error code, and we don't set
> regs->dsisr anywhere AFAICS. So it might just contain some junk.
We pass r5=0 in ISI but r5=SPRN_ESR in DSI.
And r5 is also saved into _ESR(r11)
And in asm-offset.c, we have:
STACK_PT_REGS_OFFSET(_ESR, dsisr);
So regs->dsisr has the expected content.
Christophe
>
> cheers
>
>> diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
>> index 8432c281de92..b5047f9b5dec 100644
>> --- a/arch/powerpc/mm/fault.c
>> +++ b/arch/powerpc/mm/fault.c
>> @@ -645,6 +645,7 @@ NOKPROBE_SYMBOL(do_page_fault);
>> void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
>> {
>> const struct exception_table_entry *entry;
>> + int is_write = page_fault_is_write(regs->dsisr);
>>
>> /* Are we prepared to handle this fault? */
>> if ((entry = search_exception_tables(regs->nip)) != NULL) {
>> @@ -658,9 +659,10 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
>> case 0x300:
>> case 0x380:
>> case 0xe00:
>> - pr_alert("BUG: %s at 0x%08lx\n",
>> + pr_alert("BUG: %s on %s at 0x%08lx\n",
>> regs->dar < PAGE_SIZE ? "Kernel NULL pointer dereference" :
>> - "Unable to handle kernel data access", regs->dar);
>> + "Unable to handle kernel data access",
>> + is_write ? "write" : "read", regs->dar);
>
>> break;
>> case 0x400:
>> case 0x480:
>> --
>> 2.13.3
^ permalink raw reply
* Re: [PATCH v5 3/5] powerpc/64: make buildable without CONFIG_COMPAT
From: Michal Suchánek @ 2019-08-30 7:54 UTC (permalink / raw)
To: Christophe Leroy
Cc: Michael Neuling, Arnd Bergmann, Nicolai Stange, David Hildenbrand,
Greg Kroah-Hartman, Andrew Donnellan, Heiko Carstens,
linux-kernel, Nicholas Piggin, David Howells, Hari Bathini,
Paul Mackerras, Joel Stanley, Christian Brauner, Firoz Khan,
Breno Leitao, Geert Uytterhoeven, Thomas Gleixner, linuxppc-dev,
Allison Randal, Eric W. Biederman
In-Reply-To: <8a755a692fb26b04aa4f95dccc20b076ef7dcf0c.1567146181.git.christophe.leroy@c-s.fr>
On Fri, 30 Aug 2019 06:35:13 +0000 (UTC)
Christophe Leroy <christophe.leroy@c-s.fr> wrote:
> On 08/29/2019 10:28 PM, Michal Suchanek wrote:
> > There are numerous references to 32bit functions in generic and 64bit
> > code so ifdef them out.
> >
> > Signed-off-by: Michal Suchanek <msuchanek@suse.de>
> > ---
> > v2:
> > - fix 32bit ifdef condition in signal.c
> > - simplify the compat ifdef condition in vdso.c - 64bit is redundant
> > - simplify the compat ifdef condition in callchain.c - 64bit is redundant
> > v3:
> > - use IS_ENABLED and maybe_unused where possible
> > - do not ifdef declarations
> > - clean up Makefile
> > v4:
> > - further makefile cleanup
> > - simplify is_32bit_task conditions
> > - avoid ifdef in condition by using return
> > v5:
> > - avoid unreachable code on 32bit
> > - make is_current_64bit constant on !COMPAT
> > - add stub perf_callchain_user_32 to avoid some ifdefs
> > ---
> > arch/powerpc/include/asm/thread_info.h | 4 ++--
> > arch/powerpc/kernel/Makefile | 7 +++----
> > arch/powerpc/kernel/entry_64.S | 2 ++
> > arch/powerpc/kernel/signal.c | 3 +--
> > arch/powerpc/kernel/syscall_64.c | 6 ++----
> > arch/powerpc/kernel/vdso.c | 5 ++---
> > arch/powerpc/perf/callchain.c | 13 +++++++++++--
> > 7 files changed, 23 insertions(+), 17 deletions(-)
> >
> [...]
>
> > diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
> > index c84bbd4298a0..881be5c4e9bb 100644
> > --- a/arch/powerpc/perf/callchain.c
> > +++ b/arch/powerpc/perf/callchain.c
> > @@ -15,7 +15,7 @@
> > #include <asm/sigcontext.h>
> > #include <asm/ucontext.h>
> > #include <asm/vdso.h>
> > -#ifdef CONFIG_PPC64
> > +#ifdef CONFIG_COMPAT
> > #include "../kernel/ppc32.h"
> > #endif
> > #include <asm/pte-walk.h>
> > @@ -291,7 +291,8 @@ static inline int current_is_64bit(void)
> > * interrupt stack, and the thread flags don't get copied over
> > * from the thread_info on the main stack to the interrupt stack.
> > */
> > - return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
> > + return !IS_ENABLED(CONFIG_COMPAT) ||
> > + !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
> > }
> >
> > #else /* CONFIG_PPC64 */
> > @@ -341,6 +342,7 @@ static inline int valid_user_sp(unsigned long sp, int is_64)
> >
> > #endif /* CONFIG_PPC64 */
> >
> > +#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
> > /*
> > * Layout for non-RT signal frames
> > */
> > @@ -482,6 +484,13 @@ static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> > sp = next_sp;
> > }
> > }
> > +#else /* 32bit */
> > +static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> > + struct pt_regs *regs)
> > +{
> > + (void)&read_user_stack_32; /* unused if !COMPAT */
>
> That looks pretty much like a hack.
>
> See possible alternative below.
>
> > +}
> > +#endif /* 32bit */
> >
> > void
> > perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
> >
>
> ---
> arch/powerpc/perf/callchain.c | 62 +++++++++++++++++++------------------------
> 1 file changed, 27 insertions(+), 35 deletions(-)
>
> diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
> index 881be5c4e9bb..1b169b32776a 100644
> --- a/arch/powerpc/perf/callchain.c
> +++ b/arch/powerpc/perf/callchain.c
> @@ -165,22 +165,6 @@ static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
> return read_user_stack_slow(ptr, ret, 8);
> }
>
> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> -{
> - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> - ((unsigned long)ptr & 3))
> - return -EFAULT;
> -
> - pagefault_disable();
> - if (!__get_user_inatomic(*ret, ptr)) {
> - pagefault_enable();
> - return 0;
> - }
> - pagefault_enable();
> -
> - return read_user_stack_slow(ptr, ret, 4);
> -}
> -
> static inline int valid_user_sp(unsigned long sp, int is_64)
> {
> if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x100000000UL) - 32)
> @@ -296,25 +280,10 @@ static inline int current_is_64bit(void)
> }
>
> #else /* CONFIG_PPC64 */
> -/*
> - * On 32-bit we just access the address and let hash_page create a
> - * HPTE if necessary, so there is no need to fall back to reading
> - * the page tables. Since this is called at interrupt level,
> - * do_page_fault() won't treat a DSI as a page fault.
> - */
> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> -{
> - int rc;
> -
> - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> - ((unsigned long)ptr & 3))
> - return -EFAULT;
>
> - pagefault_disable();
> - rc = __get_user_inatomic(*ret, ptr);
> - pagefault_enable();
> -
> - return rc;
> +static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
> +{
> + return 0;
> }
>
> static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
> @@ -344,6 +313,30 @@ static inline int valid_user_sp(unsigned long sp, int is_64)
>
> #if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
> /*
> + * On 32-bit we just access the address and let hash_page create a
> + * HPTE if necessary, so there is no need to fall back to reading
> + * the page tables. Since this is called at interrupt level,
> + * do_page_fault() won't treat a DSI as a page fault.
> + */
> +static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
> +{
> + int rc;
> +
> + if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
> + ((unsigned long)ptr & 3))
> + return -EFAULT;
> +
> + pagefault_disable();
> + rc = __get_user_inatomic(*ret, ptr);
> + pagefault_enable();
> +
> + if (IS_ENABLED(CONFIG_PPC32) || !rc)
> + return rc;
> +
> + return read_user_stack_slow(ptr, ret, 4);
Which is not declared here. This is not intended to be the final state,
anyway.
Thanks
Michal
> +}
> +
> +/*
> * Layout for non-RT signal frames
> */
> struct signal_frame_32 {
> @@ -488,7 +481,6 @@ static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
> struct pt_regs *regs)
> {
> - (void)&read_user_stack_32; /* unused if !COMPAT */
> }
> #endif /* 32bit */
>
^ permalink raw reply
* Re: [PATCH v5 3/5] powerpc/64: make buildable without CONFIG_COMPAT
From: Christophe Leroy @ 2019-08-30 8:01 UTC (permalink / raw)
To: Michal Suchánek
Cc: Michael Neuling, Arnd Bergmann, Nicolai Stange, David Hildenbrand,
Greg Kroah-Hartman, Andrew Donnellan, Heiko Carstens,
linux-kernel, Nicholas Piggin, David Howells, Hari Bathini,
Paul Mackerras, Joel Stanley, Christian Brauner, Firoz Khan,
Breno Leitao, Geert Uytterhoeven, Thomas Gleixner, linuxppc-dev,
Allison Randal, Eric W. Biederman
In-Reply-To: <20190830095451.47ab750f@naga>
Le 30/08/2019 à 09:54, Michal Suchánek a écrit :
> On Fri, 30 Aug 2019 06:35:13 +0000 (UTC)
> Christophe Leroy <christophe.leroy@c-s.fr> wrote:
>
>> On 08/29/2019 10:28 PM, Michal Suchanek wrote:
>>> There are numerous references to 32bit functions in generic and 64bit
>>> code so ifdef them out.
>>>
>>> Signed-off-by: Michal Suchanek <msuchanek@suse.de>
>>> ---
>>> v2:
>>> - fix 32bit ifdef condition in signal.c
>>> - simplify the compat ifdef condition in vdso.c - 64bit is redundant
>>> - simplify the compat ifdef condition in callchain.c - 64bit is redundant
>>> v3:
>>> - use IS_ENABLED and maybe_unused where possible
>>> - do not ifdef declarations
>>> - clean up Makefile
>>> v4:
>>> - further makefile cleanup
>>> - simplify is_32bit_task conditions
>>> - avoid ifdef in condition by using return
>>> v5:
>>> - avoid unreachable code on 32bit
>>> - make is_current_64bit constant on !COMPAT
>>> - add stub perf_callchain_user_32 to avoid some ifdefs
>>> ---
>>> arch/powerpc/include/asm/thread_info.h | 4 ++--
>>> arch/powerpc/kernel/Makefile | 7 +++----
>>> arch/powerpc/kernel/entry_64.S | 2 ++
>>> arch/powerpc/kernel/signal.c | 3 +--
>>> arch/powerpc/kernel/syscall_64.c | 6 ++----
>>> arch/powerpc/kernel/vdso.c | 5 ++---
>>> arch/powerpc/perf/callchain.c | 13 +++++++++++--
>>> 7 files changed, 23 insertions(+), 17 deletions(-)
>>>
>> [...]
>>
>>> diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
>>> index c84bbd4298a0..881be5c4e9bb 100644
>>> --- a/arch/powerpc/perf/callchain.c
>>> +++ b/arch/powerpc/perf/callchain.c
>>> @@ -15,7 +15,7 @@
>>> #include <asm/sigcontext.h>
>>> #include <asm/ucontext.h>
>>> #include <asm/vdso.h>
>>> -#ifdef CONFIG_PPC64
>>> +#ifdef CONFIG_COMPAT
>>> #include "../kernel/ppc32.h"
>>> #endif
>>> #include <asm/pte-walk.h>
>>> @@ -291,7 +291,8 @@ static inline int current_is_64bit(void)
>>> * interrupt stack, and the thread flags don't get copied over
>>> * from the thread_info on the main stack to the interrupt stack.
>>> */
>>> - return !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
>>> + return !IS_ENABLED(CONFIG_COMPAT) ||
>>> + !test_ti_thread_flag(task_thread_info(current), TIF_32BIT);
>>> }
>>>
>>> #else /* CONFIG_PPC64 */
>>> @@ -341,6 +342,7 @@ static inline int valid_user_sp(unsigned long sp, int is_64)
>>>
>>> #endif /* CONFIG_PPC64 */
>>>
>>> +#if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
>>> /*
>>> * Layout for non-RT signal frames
>>> */
>>> @@ -482,6 +484,13 @@ static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
>>> sp = next_sp;
>>> }
>>> }
>>> +#else /* 32bit */
>>> +static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
>>> + struct pt_regs *regs)
>>> +{
>>> + (void)&read_user_stack_32; /* unused if !COMPAT */
>>
>> That looks pretty much like a hack.
>>
>> See possible alternative below.
>>
>>> +}
>>> +#endif /* 32bit */
>>>
>>> void
>>> perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs)
>>>
>>
>> ---
>> arch/powerpc/perf/callchain.c | 62 +++++++++++++++++++------------------------
>> 1 file changed, 27 insertions(+), 35 deletions(-)
>>
>> diff --git a/arch/powerpc/perf/callchain.c b/arch/powerpc/perf/callchain.c
>> index 881be5c4e9bb..1b169b32776a 100644
>> --- a/arch/powerpc/perf/callchain.c
>> +++ b/arch/powerpc/perf/callchain.c
>> @@ -165,22 +165,6 @@ static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
>> return read_user_stack_slow(ptr, ret, 8);
>> }
>>
>> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
>> -{
>> - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
>> - ((unsigned long)ptr & 3))
>> - return -EFAULT;
>> -
>> - pagefault_disable();
>> - if (!__get_user_inatomic(*ret, ptr)) {
>> - pagefault_enable();
>> - return 0;
>> - }
>> - pagefault_enable();
>> -
>> - return read_user_stack_slow(ptr, ret, 4);
>> -}
>> -
>> static inline int valid_user_sp(unsigned long sp, int is_64)
>> {
>> if (!sp || (sp & 7) || sp > (is_64 ? TASK_SIZE : 0x100000000UL) - 32)
>> @@ -296,25 +280,10 @@ static inline int current_is_64bit(void)
>> }
>>
>> #else /* CONFIG_PPC64 */
>> -/*
>> - * On 32-bit we just access the address and let hash_page create a
>> - * HPTE if necessary, so there is no need to fall back to reading
>> - * the page tables. Since this is called at interrupt level,
>> - * do_page_fault() won't treat a DSI as a page fault.
>> - */
>> -static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
>> -{
>> - int rc;
>> -
>> - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
>> - ((unsigned long)ptr & 3))
>> - return -EFAULT;
>>
>> - pagefault_disable();
>> - rc = __get_user_inatomic(*ret, ptr);
>> - pagefault_enable();
>> -
>> - return rc;
>> +static int read_user_stack_slow(void __user *ptr, void *buf, int nb)
>> +{
>> + return 0;
Here it is
>> }
>>
>> static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
>> @@ -344,6 +313,30 @@ static inline int valid_user_sp(unsigned long sp, int is_64)
>>
>> #if defined(CONFIG_PPC32) || defined(CONFIG_COMPAT)
>> /*
>> + * On 32-bit we just access the address and let hash_page create a
>> + * HPTE if necessary, so there is no need to fall back to reading
>> + * the page tables. Since this is called at interrupt level,
>> + * do_page_fault() won't treat a DSI as a page fault.
>> + */
>> +static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
>> +{
>> + int rc;
>> +
>> + if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
>> + ((unsigned long)ptr & 3))
>> + return -EFAULT;
>> +
>> + pagefault_disable();
>> + rc = __get_user_inatomic(*ret, ptr);
>> + pagefault_enable();
>> +
>> + if (IS_ENABLED(CONFIG_PPC32) || !rc)
>> + return rc;
>> +
>> + return read_user_stack_slow(ptr, ret, 4);
> Which is not declared here. This is not intended to be the final state,
> anyway.
Yes it is declared here, see above
Christophe
>
> Thanks
>
> Michal
>> +}
>> +
>> +/*
>> * Layout for non-RT signal frames
>> */
>> struct signal_frame_32 {
>> @@ -488,7 +481,6 @@ static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
>> static void perf_callchain_user_32(struct perf_callchain_entry_ctx *entry,
>> struct pt_regs *regs)
>> {
>> - (void)&read_user_stack_32; /* unused if !COMPAT */
>> }
>> #endif /* 32bit */
>>
^ permalink raw reply
* Re: [PATCH -next] crypto: nx - remove unused variables 'nx_driver_string' and 'nx_driver_version'
From: Herbert Xu @ 2019-08-30 8:24 UTC (permalink / raw)
To: YueHaibing
Cc: nayna, linux-kernel, pfsmorigo, linux-crypto, leitao, paulus,
linuxppc-dev, davem
In-Reply-To: <20190822144649.19880-1-yuehaibing@huawei.com>
On Thu, Aug 22, 2019 at 10:46:49PM +0800, YueHaibing wrote:
> drivers/crypto/nx/nx.h:12:19: warning:
> nx_driver_string defined but not used [-Wunused-const-variable=]
> drivers/crypto/nx/nx.h:13:19: warning:
> nx_driver_version defined but not used [-Wunused-const-variable=]
>
> They are never used, so just remove it.
>
> Reported-by: Hulk Robot <hulkci@huawei.com>
> Signed-off-by: YueHaibing <yuehaibing@huawei.com>
> ---
> drivers/crypto/nx/nx.h | 3 ---
> 1 file changed, 3 deletions(-)
Patch applied. Thanks.
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: Oops (request_key_auth_describe) while running cve-2016-7042 from LTP
From: Hillf Danton @ 2019-08-30 8:56 UTC (permalink / raw)
To: Sachin Sant; +Cc: dhowells, linuxppc-dev, keyrings, linux-kernel
On Fri, 30 Aug 2019 12:18:07 +0530 Sachin Sant wrote:
>
> [ 8074.351033] BUG: Kernel NULL pointer dereference at 0x00000038
> [ 8074.351046] Faulting instruction address: 0xc0000000004ddf30
> [ 8074.351052] Oops: Kernel access of bad area, sig: 11 [#1]
> [ 8074.351056] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
Add rcu gp.
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -64,12 +64,19 @@ static int request_key_auth_instantiate(
static void request_key_auth_describe(const struct key *key,
struct seq_file *m)
{
- struct request_key_auth *rka = dereference_key_rcu(key);
+ struct request_key_auth *rka;
+
+ rcu_read_lock();
+ rka = dereference_key_rcu(key);
+ if (!rka)
+ goto out;
seq_puts(m, "key:");
seq_puts(m, key->description);
if (key_is_positive(key))
seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
+out:
+ rcu_read_unlock();
}
/*
^ permalink raw reply
* [PATCH v4 3/8] mm/memory_hotplug: Shrink zones when offlining memory
From: David Hildenbrand @ 2019-08-30 9:14 UTC (permalink / raw)
To: linux-kernel
Cc: Mark Rutland, linux-s390, Rich Felker, linux-ia64,
David Hildenbrand, Peter Zijlstra, Catalin Marinas, Dave Hansen,
Heiko Carstens, Wei Yang, linux-mm, Michal Hocko, Paul Mackerras,
H. Peter Anvin, Will Deacon, Dan Williams, Halil Pasic, Yu Zhao,
Yoshinori Sato, Jason Gunthorpe, linux-sh, x86,
Matthew Wilcox (Oracle), Mike Rapoport, Jun Yao,
Christian Borntraeger, Ingo Molnar, linux-arm-kernel, Ira Weiny,
Fenghua Yu, Pavel Tatashin, Vasily Gorbik, Anshuman Khandual,
Masahiro Yamada, linuxppc-dev, Borislav Petkov, Andy Lutomirski,
Thomas Gleixner, Gerald Schaefer, Oscar Salvador, Tony Luck,
Steve Capper, Greg Kroah-Hartman, Logan Gunthorpe, Tom Lendacky,
Aneesh Kumar K.V, Qian Cai, Andrew Morton, Robin Murphy
In-Reply-To: <20190830091428.18399-1-david@redhat.com>
We currently try to shrink a single zone when removing memory. We use the
zone of the first page of the memory we are removing. If that memmap was
never initialized (e.g., memory was never onlined), we will read garbage
and can trigger kernel BUGs (due to a stale pointer):
:/# [ 23.912993] BUG: unable to handle page fault for address: 000000000000353d
[ 23.914219] #PF: supervisor write access in kernel mode
[ 23.915199] #PF: error_code(0x0002) - not-present page
[ 23.916160] PGD 0 P4D 0
[ 23.916627] Oops: 0002 [#1] SMP PTI
[ 23.917256] CPU: 1 PID: 7 Comm: kworker/u8:0 Not tainted 5.3.0-rc5-next-20190820+ #317
[ 23.918900] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.4
[ 23.921194] Workqueue: kacpi_hotplug acpi_hotplug_work_fn
[ 23.922249] RIP: 0010:clear_zone_contiguous+0x5/0x10
[ 23.923173] Code: 48 89 c6 48 89 c3 e8 2a fe ff ff 48 85 c0 75 cf 5b 5d c3 c6 85 fd 05 00 00 01 5b 5d c3 0f 1f 840
[ 23.926876] RSP: 0018:ffffad2400043c98 EFLAGS: 00010246
[ 23.927928] RAX: 0000000000000000 RBX: 0000000200000000 RCX: 0000000000000000
[ 23.929458] RDX: 0000000000200000 RSI: 0000000000140000 RDI: 0000000000002f40
[ 23.930899] RBP: 0000000140000000 R08: 0000000000000000 R09: 0000000000000001
[ 23.932362] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000140000
[ 23.933603] R13: 0000000000140000 R14: 0000000000002f40 R15: ffff9e3e7aff3680
[ 23.934913] FS: 0000000000000000(0000) GS:ffff9e3e7bb00000(0000) knlGS:0000000000000000
[ 23.936294] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 23.937481] CR2: 000000000000353d CR3: 0000000058610000 CR4: 00000000000006e0
[ 23.938687] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 23.939889] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
[ 23.941168] Call Trace:
[ 23.941580] __remove_pages+0x4b/0x640
[ 23.942303] ? mark_held_locks+0x49/0x70
[ 23.943149] arch_remove_memory+0x63/0x8d
[ 23.943921] try_remove_memory+0xdb/0x130
[ 23.944766] ? walk_memory_blocks+0x7f/0x9e
[ 23.945616] __remove_memory+0xa/0x11
[ 23.946274] acpi_memory_device_remove+0x70/0x100
[ 23.947308] acpi_bus_trim+0x55/0x90
[ 23.947914] acpi_device_hotplug+0x227/0x3a0
[ 23.948714] acpi_hotplug_work_fn+0x1a/0x30
[ 23.949433] process_one_work+0x221/0x550
[ 23.950190] worker_thread+0x50/0x3b0
[ 23.950993] kthread+0x105/0x140
[ 23.951644] ? process_one_work+0x550/0x550
[ 23.952508] ? kthread_park+0x80/0x80
[ 23.953367] ret_from_fork+0x3a/0x50
[ 23.954025] Modules linked in:
[ 23.954613] CR2: 000000000000353d
[ 23.955248] ---[ end trace 93d982b1fb3e1a69 ]---
Instead, shrink the zones when offlining memory or when onlining failed.
Introduce and use remove_pfn_range_from_zone(() for that. We now properly
shrink the zones, even if we have DIMMs whereby
- Some memory blocks fall into no zone (never onlined)
- Some memory blocks fall into multiple zones (offlined+re-onlined)
- Multiple memory blocks that fall into different zones
Drop the zone parameter (with a potential dubious value) from
__remove_pages() and __remove_section().
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Yoshinori Sato <ysato@users.sourceforge.jp>
Cc: Rich Felker <dalias@libc.org>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Steve Capper <steve.capper@arm.com>
Cc: Mike Rapoport <rppt@linux.ibm.com>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>
Cc: Yu Zhao <yuzhao@google.com>
Cc: Jun Yao <yaojun8558363@gmail.com>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
Cc: Christophe Leroy <christophe.leroy@c-s.fr>
Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.ibm.com>
Cc: Pavel Tatashin <pasha.tatashin@soleen.com>
Cc: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Cc: Halil Pasic <pasic@linux.ibm.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Wei Yang <richard.weiyang@gmail.com>
Cc: Qian Cai <cai@lca.pw>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Logan Gunthorpe <logang@deltatee.com>
Cc: Ira Weiny <ira.weiny@intel.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-ia64@vger.kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-s390@vger.kernel.org
Cc: linux-sh@vger.kernel.org
Fixes: d0dc12e86b31 ("mm/memory_hotplug: optimize memory hotplug")
Signed-off-by: David Hildenbrand <david@redhat.com>
---
arch/arm64/mm/mmu.c | 4 +---
arch/ia64/mm/init.c | 4 +---
arch/powerpc/mm/mem.c | 3 +--
arch/s390/mm/init.c | 4 +---
arch/sh/mm/init.c | 4 +---
arch/x86/mm/init_32.c | 4 +---
arch/x86/mm/init_64.c | 4 +---
include/linux/memory_hotplug.h | 7 +++++--
mm/memory_hotplug.c | 31 ++++++++++++++++---------------
mm/memremap.c | 3 +--
10 files changed, 29 insertions(+), 39 deletions(-)
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 60c929f3683b..d10247fab0fd 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -1069,7 +1069,6 @@ void arch_remove_memory(int nid, u64 start, u64 size,
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
- struct zone *zone;
/*
* FIXME: Cleanup page tables (also in arch_add_memory() in case
@@ -1078,7 +1077,6 @@ void arch_remove_memory(int nid, u64 start, u64 size,
* unplug. ARCH_ENABLE_MEMORY_HOTREMOVE must not be
* unlocked yet.
*/
- zone = page_zone(pfn_to_page(start_pfn));
- __remove_pages(zone, start_pfn, nr_pages, altmap);
+ __remove_pages(start_pfn, nr_pages, altmap);
}
#endif
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index bf9df2625bc8..a6dd80a2c939 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -689,9 +689,7 @@ void arch_remove_memory(int nid, u64 start, u64 size,
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
- struct zone *zone;
- zone = page_zone(pfn_to_page(start_pfn));
- __remove_pages(zone, start_pfn, nr_pages, altmap);
+ __remove_pages(start_pfn, nr_pages, altmap);
}
#endif
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 69f99128a8d6..f3a5e397b911 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -130,10 +130,9 @@ void __ref arch_remove_memory(int nid, u64 start, u64 size,
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
- struct page *page = pfn_to_page(start_pfn) + vmem_altmap_offset(altmap);
int ret;
- __remove_pages(page_zone(page), start_pfn, nr_pages, altmap);
+ __remove_pages(start_pfn, nr_pages, altmap);
/* Remove htab bolted mappings for this section of memory */
start = (unsigned long)__va(start);
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 20340a03ad90..6f13eb66e375 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -296,10 +296,8 @@ void arch_remove_memory(int nid, u64 start, u64 size,
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
- struct zone *zone;
- zone = page_zone(pfn_to_page(start_pfn));
- __remove_pages(zone, start_pfn, nr_pages, altmap);
+ __remove_pages(start_pfn, nr_pages, altmap);
vmem_remove_mapping(start, size);
}
#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index dfdbaa50946e..d1b1ff2be17a 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -434,9 +434,7 @@ void arch_remove_memory(int nid, u64 start, u64 size,
{
unsigned long start_pfn = PFN_DOWN(start);
unsigned long nr_pages = size >> PAGE_SHIFT;
- struct zone *zone;
- zone = page_zone(pfn_to_page(start_pfn));
- __remove_pages(zone, start_pfn, nr_pages, altmap);
+ __remove_pages(start_pfn, nr_pages, altmap);
}
#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 4068abb9427f..9d036be27aaa 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -865,10 +865,8 @@ void arch_remove_memory(int nid, u64 start, u64 size,
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
- struct zone *zone;
- zone = page_zone(pfn_to_page(start_pfn));
- __remove_pages(zone, start_pfn, nr_pages, altmap);
+ __remove_pages(start_pfn, nr_pages, altmap);
}
#endif
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index a6b5c653727b..b8541d77452c 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1212,10 +1212,8 @@ void __ref arch_remove_memory(int nid, u64 start, u64 size,
{
unsigned long start_pfn = start >> PAGE_SHIFT;
unsigned long nr_pages = size >> PAGE_SHIFT;
- struct page *page = pfn_to_page(start_pfn) + vmem_altmap_offset(altmap);
- struct zone *zone = page_zone(page);
- __remove_pages(zone, start_pfn, nr_pages, altmap);
+ __remove_pages(start_pfn, nr_pages, altmap);
kernel_physical_mapping_remove(start, start + size);
}
#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index f46ea71b4ffd..451efd4499cc 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -125,8 +125,8 @@ static inline bool movable_node_is_enabled(void)
extern void arch_remove_memory(int nid, u64 start, u64 size,
struct vmem_altmap *altmap);
-extern void __remove_pages(struct zone *zone, unsigned long start_pfn,
- unsigned long nr_pages, struct vmem_altmap *altmap);
+extern void __remove_pages(unsigned long start_pfn, unsigned long nr_pages,
+ struct vmem_altmap *altmap);
/* reasonably generic interface to expand the physical pages */
extern int __add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
@@ -345,6 +345,9 @@ extern int add_memory(int nid, u64 start, u64 size);
extern int add_memory_resource(int nid, struct resource *resource);
extern void move_pfn_range_to_zone(struct zone *zone, unsigned long start_pfn,
unsigned long nr_pages, struct vmem_altmap *altmap);
+extern void remove_pfn_range_from_zone(struct zone *zone,
+ unsigned long start_pfn,
+ unsigned long nr_pages);
extern bool is_memblock_offlined(struct memory_block *mem);
extern int sparse_add_section(int nid, unsigned long pfn,
unsigned long nr_pages, struct vmem_altmap *altmap);
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index e0d1f6a9dfeb..4da59ec14dbb 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -457,8 +457,9 @@ static void update_pgdat_span(struct pglist_data *pgdat)
pgdat->node_spanned_pages = node_end_pfn - node_start_pfn;
}
-static void __remove_zone(struct zone *zone, unsigned long start_pfn,
- unsigned long nr_pages)
+void __ref remove_pfn_range_from_zone(struct zone *zone,
+ unsigned long start_pfn,
+ unsigned long nr_pages)
{
struct pglist_data *pgdat = zone->zone_pgdat;
unsigned long flags;
@@ -471,28 +472,30 @@ static void __remove_zone(struct zone *zone, unsigned long start_pfn,
if (zone_idx(zone) == ZONE_DEVICE)
return;
+ clear_zone_contiguous(zone);
+
pgdat_resize_lock(zone->zone_pgdat, &flags);
shrink_zone_span(zone, start_pfn, start_pfn + nr_pages);
update_pgdat_span(pgdat);
pgdat_resize_unlock(zone->zone_pgdat, &flags);
+
+ set_zone_contiguous(zone);
}
-static void __remove_section(struct zone *zone, unsigned long pfn,
- unsigned long nr_pages, unsigned long map_offset,
- struct vmem_altmap *altmap)
+static void __remove_section(unsigned long pfn, unsigned long nr_pages,
+ unsigned long map_offset,
+ struct vmem_altmap *altmap)
{
struct mem_section *ms = __nr_to_section(pfn_to_section_nr(pfn));
if (WARN_ON_ONCE(!valid_section(ms)))
return;
- __remove_zone(zone, pfn, nr_pages);
sparse_remove_section(ms, pfn, nr_pages, map_offset, altmap);
}
/**
- * __remove_pages() - remove sections of pages from a zone
- * @zone: zone from which pages need to be removed
+ * __remove_pages() - remove sections of pages
* @pfn: starting pageframe (must be aligned to start of a section)
* @nr_pages: number of pages to remove (must be multiple of section size)
* @altmap: alternative device page map or %NULL if default memmap is used
@@ -502,16 +505,14 @@ static void __remove_section(struct zone *zone, unsigned long pfn,
* sure that pages are marked reserved and zones are adjust properly by
* calling offline_pages().
*/
-void __remove_pages(struct zone *zone, unsigned long pfn,
- unsigned long nr_pages, struct vmem_altmap *altmap)
+void __remove_pages(unsigned long pfn, unsigned long nr_pages,
+ struct vmem_altmap *altmap)
{
unsigned long map_offset = 0;
unsigned long nr, start_sec, end_sec;
map_offset = vmem_altmap_offset(altmap);
- clear_zone_contiguous(zone);
-
if (check_pfn_span(pfn, nr_pages, "remove"))
return;
@@ -523,13 +524,11 @@ void __remove_pages(struct zone *zone, unsigned long pfn,
cond_resched();
pfns = min(nr_pages, PAGES_PER_SECTION
- (pfn & ~PAGE_SECTION_MASK));
- __remove_section(zone, pfn, pfns, map_offset, altmap);
+ __remove_section(pfn, pfns, map_offset, altmap);
pfn += pfns;
nr_pages -= pfns;
map_offset = 0;
}
-
- set_zone_contiguous(zone);
}
int set_online_page_callback(online_page_callback_t callback)
@@ -857,6 +856,7 @@ int __ref online_pages(unsigned long pfn, unsigned long nr_pages, int online_typ
(unsigned long long) pfn << PAGE_SHIFT,
(((unsigned long long) pfn + nr_pages) << PAGE_SHIFT) - 1);
memory_notify(MEM_CANCEL_ONLINE, &arg);
+ remove_pfn_range_from_zone(zone, pfn, nr_pages);
mem_hotplug_done();
return ret;
}
@@ -1592,6 +1592,7 @@ static int __ref __offline_pages(unsigned long start_pfn,
writeback_set_ratelimit();
memory_notify(MEM_OFFLINE, &arg);
+ remove_pfn_range_from_zone(zone, start_pfn, nr_pages);
mem_hotplug_done();
return 0;
diff --git a/mm/memremap.c b/mm/memremap.c
index f6c17339cd0d..cb90c3e8804a 100644
--- a/mm/memremap.c
+++ b/mm/memremap.c
@@ -139,8 +139,7 @@ void memunmap_pages(struct dev_pagemap *pgmap)
mem_hotplug_begin();
if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
pfn = PHYS_PFN(res->start);
- __remove_pages(page_zone(pfn_to_page(pfn)), pfn,
- PHYS_PFN(resource_size(res)), NULL);
+ __remove_pages(pfn, PHYS_PFN(resource_size(res)), NULL);
} else {
arch_remove_memory(nid, res->start, resource_size(res),
pgmap_altmap(pgmap));
--
2.21.0
^ permalink raw reply related
* Re: Oops (request_key_auth_describe) while running cve-2016-7042 from LTP
From: Sachin Sant @ 2019-08-30 10:32 UTC (permalink / raw)
To: Hillf Danton; +Cc: dhowells, linuxppc-dev, keyrings, linux-kernel
In-Reply-To: <20190830085646.14740-1-hdanton@sina.com>
> On 30-Aug-2019, at 2:26 PM, Hillf Danton <hdanton@sina.com> wrote:
>
>
> On Fri, 30 Aug 2019 12:18:07 +0530 Sachin Sant wrote:
>>
>> [ 8074.351033] BUG: Kernel NULL pointer dereference at 0x00000038
>> [ 8074.351046] Faulting instruction address: 0xc0000000004ddf30
>> [ 8074.351052] Oops: Kernel access of bad area, sig: 11 [#1]
>> [ 8074.351056] LE PAGE_SIZE=64K MMU=Hash SMP NR_CPUS=2048 NUMA pSeries
>
> Add rcu gp.
>
> --- a/security/keys/request_key_auth.c
> +++ b/security/keys/request_key_auth.c
> @@ -64,12 +64,19 @@ static int request_key_auth_instantiate(
> static void request_key_auth_describe(const struct key *key,
> struct seq_file *m)
> {
> - struct request_key_auth *rka = dereference_key_rcu(key);
> + struct request_key_auth *rka;
> +
> + rcu_read_lock();
> + rka = dereference_key_rcu(key);
> + if (!rka)
> + goto out;
>
Thanks for the patch. Works for me. Test ran fine without any problems.
Tested-by: Sachin Sant <sachinp@linux.vnet.ibm.com>
Thanks
-Sachin
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox