Patch 3 fixes the userspace segfaults caused by the PVCLOCK_FIXMAP user mapping (which I've copied from the 3.2 kaiser patchset). I don't claim I fully understand this so the fix might be too broad.
Andrea Arcangeli (1): x86/mm/kaiser: remove paravirt clock warning
Juerg Haefliger (3): Revert "x86: kvmclock: Disable use from vDSO if KPTI is enabled" x86/kaiser: Add PVCLOCK_FIXMAP user mapping x86/kaiser: Fix segfaults caused by the PVCLOCK_FIXMAP user mapping
Marcelo Tosatti (1): kvmclock: export kvmclock clocksource and data pointers
arch/x86/include/asm/kvmclock.h | 6 ++++++ arch/x86/kernel/kvmclock.c | 9 +++------ arch/x86/mm/kaiser.c | 12 +++++++++++- 3 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 arch/x86/include/asm/kvmclock.h
This reverts commit abe3029e4febfa18e4a9562a792465182b3992a0.
Signed-off-by: Juerg Haefliger juerg.haefliger@canonical.com --- arch/x86/kernel/kvmclock.c | 5 ----- arch/x86/mm/kaiser.c | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index 206aa5a2afe0..a2de9bc7ac0b 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -24,7 +24,6 @@ #include <linux/percpu.h> #include <linux/hardirq.h> #include <linux/memblock.h> -#include <linux/kaiser.h>
#include <asm/x86_init.h> #include <asm/reboot.h> @@ -282,10 +281,6 @@ int __init kvm_setup_vsyscall_timeinfo(void) if (!hv_clock) return 0;
- /* FIXME: Need to add pvclock pages to user-space page tables */ - if (kaiser_enabled) - return 0; - size = PAGE_ALIGN(sizeof(struct pvclock_vsyscall_time_info)*NR_CPUS);
preempt_disable(); diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c index 8d1019d176e2..8b5939649088 100644 --- a/arch/x86/mm/kaiser.c +++ b/arch/x86/mm/kaiser.c @@ -322,7 +322,7 @@ silent_disable: */ void __init kaiser_init(void) { - int cpu, idx; + int cpu;
if (!kaiser_enabled) return;
Code lifted from patch 'x86/mm/kaiser: re-enable vsyscalls', courtesy of Andrea Arcangeli aarcange@redhat.com.
Signed-off-by: Juerg Haefliger juerg.haefliger@canonical.com --- arch/x86/mm/kaiser.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c index 8b5939649088..fc50dee484f6 100644 --- a/arch/x86/mm/kaiser.c +++ b/arch/x86/mm/kaiser.c @@ -322,7 +322,7 @@ silent_disable: */ void __init kaiser_init(void) { - int cpu; + int cpu, idx;
if (!kaiser_enabled) return; @@ -371,6 +371,14 @@ void __init kaiser_init(void) kaiser_add_user_map_early((void *)VSYSCALL_ADDR, PAGE_SIZE, vsyscall_pgprot);
+#ifdef CONFIG_PARAVIRT_CLOCK + for (idx = 0; idx <= (PVCLOCK_FIXMAP_END-PVCLOCK_FIXMAP_BEGIN); idx++) { + kaiser_add_user_map_early((void *)__fix_to_virt(PVCLOCK_FIXMAP_BEGIN + idx), + PAGE_SIZE, + __PAGE_KERNEL_VVAR | _PAGE_GLOBAL); + } +#endif + pr_info("enabled\n"); }
Without this, we'll get early userspace segfaults like this in the PVCLOCK_FIXMAP area:
[ 0.602244] init[1]: segfault at ffffffffff5ff020 ip 00007fff7154afc1 sp 00007fff71540c08 error 5 [ 0.603026] Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b [ 0.603026] [ 0.603624] CPU: 0 PID: 1 Comm: init Not tainted 3.16.53-rc2-stable+ #240 [ 0.604002] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1ubuntu1 04/01/2014 [ 0.604002] 0000000000000000 ffff88003e31bc80 ffffffff81741db3 ffffffff81a60558 [ 0.604002] ffff88003d222380 ffff88003e31bcf8 ffffffff8173da0e 0000000000000010 [ 0.604002] ffff88003e31bd08 ffff88003e31bca8 0000000000000000 000000000000000b [ 0.604002] Call Trace: [ 0.604002] [<ffffffff81741db3>] dump_stack+0x64/0x82 [ 0.604002] [<ffffffff8173da0e>] panic+0xc8/0x203 [ 0.604002] [<ffffffff8109c7f0>] do_exit+0xb00/0xb00 [ 0.604002] [<ffffffff8109d5ff>] do_group_exit+0x3f/0xa0 [ 0.604002] [<ffffffff810ac9c2>] get_signal_to_deliver+0x1c2/0x5e0 [ 0.604002] [<ffffffff810494f8>] do_signal+0x48/0x730 [ 0.604002] [<ffffffff8173d70c>] ? __bad_area_nosemaphore+0x1bd/0x1ca [ 0.604002] [<ffffffff8108cad4>] ? __do_page_fault+0x84/0x400 [ 0.604002] [<ffffffff81049c45>] do_notify_resume+0x65/0x80 [ 0.604002] [<ffffffff8174c002>] retint_signal+0x48/0x86 [ 0.604002] Kernel Offset: 0x0 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffff9fffffff) [ 0.604002] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
This is probably too big of a hammer and needs some polishing but it's working :-)
Signed-off-by: Juerg Haefliger juerg.haefliger@canonical.com --- arch/x86/mm/kaiser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c index fc50dee484f6..3f0b0b41badc 100644 --- a/arch/x86/mm/kaiser.c +++ b/arch/x86/mm/kaiser.c @@ -202,7 +202,7 @@ static int kaiser_add_user_map(const void *__start_addr, unsigned long size, ret = -EIO; break; } - pte = kaiser_pagetable_walk(address, flags & _PAGE_USER); + pte = kaiser_pagetable_walk(address, true); if (!pte) { ret = -ENOMEM; break;
From: Marcelo Tosatti mtosatti@redhat.com
To be used by KVM PTP driver.
Signed-off-by: Marcelo Tosatti mtosatti@redhat.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com (cherry picked from commit f4066c2bc4d0de4e5dcbff21dae41e89fe8f38c0) Signed-off-by: Juerg Haefliger juerg.haefliger@canonical.com --- arch/x86/include/asm/kvmclock.h | 6 ++++++ arch/x86/kernel/kvmclock.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 arch/x86/include/asm/kvmclock.h
diff --git a/arch/x86/include/asm/kvmclock.h b/arch/x86/include/asm/kvmclock.h new file mode 100644 index 000000000000..f260bef63591 --- /dev/null +++ b/arch/x86/include/asm/kvmclock.h @@ -0,0 +1,6 @@ +#ifndef _ASM_X86_KVM_CLOCK_H +#define _ASM_X86_KVM_CLOCK_H + +extern struct clocksource kvm_clock; + +#endif /* _ASM_X86_KVM_CLOCK_H */ diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index a2de9bc7ac0b..321c2acf0025 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -27,6 +27,7 @@
#include <asm/x86_init.h> #include <asm/reboot.h> +#include <asm/kvmclock.h>
static int kvmclock = 1; static int msr_kvm_system_time = MSR_KVM_SYSTEM_TIME; @@ -146,13 +147,14 @@ bool kvm_check_and_clear_guest_paused(void) return ret; }
-static struct clocksource kvm_clock = { +struct clocksource kvm_clock = { .name = "kvm-clock", .read = kvm_clock_get_cycles, .rating = 400, .mask = CLOCKSOURCE_MASK(64), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; +EXPORT_SYMBOL_GPL(kvm_clock);
int kvm_register_clock(char *txt) {
From: Andrea Arcangeli aarcange@redhat.com
Adding shadow pgd mappings for unmapped kernel-side areas triggers harmless boot warnings. To reduce the boot warnings (if booted on bare metal) make the fixmap mapping of pvclock region conditional to pvclock being actived at boot. KAISER is initialized after pvlock.
Signed-off-by: Andrea Arcangeli aarcange@redhat.com Signed-off-by: Juerg Haefliger juerg.haefliger@canonical.com --- arch/x86/mm/kaiser.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/x86/mm/kaiser.c b/arch/x86/mm/kaiser.c index 3f0b0b41badc..14c332caab60 100644 --- a/arch/x86/mm/kaiser.c +++ b/arch/x86/mm/kaiser.c @@ -24,6 +24,7 @@ extern struct mm_struct init_mm; #include <asm/desc.h> #include <asm/vsyscall.h> #include <asm/cmdline.h> +#include <asm/kvmclock.h>
int kaiser_enabled __read_mostly = 1; EXPORT_SYMBOL(kaiser_enabled); /* for inlined TLB flush functions */ @@ -372,7 +373,8 @@ void __init kaiser_init(void) vsyscall_pgprot);
#ifdef CONFIG_PARAVIRT_CLOCK - for (idx = 0; idx <= (PVCLOCK_FIXMAP_END-PVCLOCK_FIXMAP_BEGIN); idx++) { + for (idx = 0; kvm_clock.archdata.vclock_mode == VCLOCK_PVCLOCK && + idx <= (PVCLOCK_FIXMAP_END-PVCLOCK_FIXMAP_BEGIN); idx++) { kaiser_add_user_map_early((void *)__fix_to_virt(PVCLOCK_FIXMAP_BEGIN + idx), PAGE_SIZE, __PAGE_KERNEL_VVAR | _PAGE_GLOBAL);
linux-stable-mirror@lists.linaro.org