aboutsummaryrefslogtreecommitdiff
path: root/emulators/xen-kernel
diff options
context:
space:
mode:
authorRoger Pau Monné <royger@FreeBSD.org>2018-01-24 08:51:37 +0000
committerRoger Pau Monné <royger@FreeBSD.org>2018-01-24 08:51:37 +0000
commite9233956dd51ccf123d230fb0bd5ffc22f4839a9 (patch)
tree78f25d3d2d604a5aeded56b698e9ab2b5dacb198 /emulators/xen-kernel
parent9440661caf266a124d73cd29447fdda7725d9ed2 (diff)
downloadports-e9233956dd51ccf123d230fb0bd5ffc22f4839a9.tar.gz
ports-e9233956dd51ccf123d230fb0bd5ffc22f4839a9.zip
Notes
Diffstat (limited to 'emulators/xen-kernel')
-rw-r--r--emulators/xen-kernel/Makefile4
-rw-r--r--emulators/xen-kernel/files/0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch399
-rw-r--r--emulators/xen-kernel/files/0001-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch45
3 files changed, 447 insertions, 1 deletions
diff --git a/emulators/xen-kernel/Makefile b/emulators/xen-kernel/Makefile
index be25e49bf66b..6cd83f8e2068 100644
--- a/emulators/xen-kernel/Makefile
+++ b/emulators/xen-kernel/Makefile
@@ -2,7 +2,7 @@
PORTNAME= xen
PORTVERSION= 4.7.2
-PORTREVISION= 8
+PORTREVISION= 9
CATEGORIES= emulators
MASTER_SITES= http://downloads.xenproject.org/release/xen/${PORTVERSION}/
PKGNAMESUFFIX= -kernel
@@ -90,6 +90,8 @@ EXTRA_PATCHES= ${FILESDIR}/0001-xen-logdirty-prevent-preemption-if-finished.patc
${FILESDIR}/xsa249.patch:-p1 \
${FILESDIR}/xsa250.patch:-p1 \
${FILESDIR}/xsa251-4.8.patch:-p1 \
+ ${FILESDIR}/0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch:-p1 \
+ ${FILESDIR}/0001-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch:-p1 \
${FILESDIR}/0001-x86-Meltdown-band-aid-against-malicious-64-bit-PV-gu.patch:-p1 \
${FILESDIR}/0002-x86-allow-Meltdown-band-aid-to-be-disabled.patch:-p1
diff --git a/emulators/xen-kernel/files/0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch b/emulators/xen-kernel/files/0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch
new file mode 100644
index 000000000000..576fe192be03
--- /dev/null
+++ b/emulators/xen-kernel/files/0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch
@@ -0,0 +1,399 @@
+From 0e6c6fc449000d97f9fa87ed1fbe23f0cf21406b Mon Sep 17 00:00:00 2001
+From: Andrew Cooper <andrew.cooper3@citrix.com>
+Date: Wed, 17 Jan 2018 17:22:34 +0100
+Subject: [PATCH] x86/entry: Remove support for partial cpu_user_regs frames
+
+Save all GPRs on entry to Xen.
+
+The entry_int82() path is via a DPL1 gate, only usable by 32bit PV guests, so
+can get away with only saving the 32bit registers. All other entrypoints can
+be reached from 32 or 64bit contexts.
+
+This is part of XSA-254.
+
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Reviewed-by: Wei Liu <wei.liu2@citrix.com>
+Acked-by: Jan Beulich <jbeulich@suse.com>
+master commit: f9eb74789af77e985ae653193f3622263499f674
+master date: 2018-01-05 19:57:07 +0000
+---
+ tools/tests/x86_emulator/x86_emulate.c | 1 -
+ xen/arch/x86/domain.c | 1 -
+ xen/arch/x86/traps.c | 2 -
+ xen/arch/x86/x86_64/compat/entry.S | 7 ++-
+ xen/arch/x86/x86_64/entry.S | 12 ++--
+ xen/arch/x86/x86_64/traps.c | 13 ++--
+ xen/arch/x86/x86_emulate.c | 1 -
+ xen/arch/x86/x86_emulate/x86_emulate.c | 8 +--
+ xen/common/wait.c | 1 -
+ xen/include/asm-x86/asm_defns.h | 107 +++------------------------------
+ 10 files changed, 26 insertions(+), 127 deletions(-)
+
+diff --git a/tools/tests/x86_emulator/x86_emulate.c b/tools/tests/x86_emulator/x86_emulate.c
+index 10e3f61baa..c12527a50b 100644
+--- a/tools/tests/x86_emulator/x86_emulate.c
++++ b/tools/tests/x86_emulator/x86_emulate.c
+@@ -24,7 +24,6 @@ typedef bool bool_t;
+ #endif
+
+ #define cpu_has_amd_erratum(nr) 0
+-#define mark_regs_dirty(r) ((void)(r))
+
+ #define __packed __attribute__((packed))
+
+diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
+index ceeadabbfd..6539b75fa7 100644
+--- a/xen/arch/x86/domain.c
++++ b/xen/arch/x86/domain.c
+@@ -148,7 +148,6 @@ static void noreturn continue_idle_domain(struct vcpu *v)
+ static void noreturn continue_nonidle_domain(struct vcpu *v)
+ {
+ check_wakeup_from_wait();
+- mark_regs_dirty(guest_cpu_user_regs());
+ reset_stack_and_jump(ret_from_intr);
+ }
+
+diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
+index 05b4b0811d..0928c9b235 100644
+--- a/xen/arch/x86/traps.c
++++ b/xen/arch/x86/traps.c
+@@ -2456,7 +2456,6 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
+ goto fail;
+ if ( admin_io_okay(port, op_bytes, currd) )
+ {
+- mark_regs_dirty(regs);
+ io_emul(regs);
+ }
+ else
+@@ -2486,7 +2485,6 @@ static int emulate_privileged_op(struct cpu_user_regs *regs)
+ goto fail;
+ if ( admin_io_okay(port, op_bytes, currd) )
+ {
+- mark_regs_dirty(regs);
+ io_emul(regs);
+ if ( (op_bytes == 1) && pv_post_outb_hook )
+ pv_post_outb_hook(port, regs->eax);
+diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S
+index 794bb44266..7ee01597a3 100644
+--- a/xen/arch/x86/x86_64/compat/entry.S
++++ b/xen/arch/x86/x86_64/compat/entry.S
+@@ -15,7 +15,8 @@
+ ENTRY(compat_hypercall)
+ ASM_CLAC
+ pushq $0
+- SAVE_VOLATILE type=TRAP_syscall compat=1
++ movl $TRAP_syscall, 4(%rsp)
++ SAVE_ALL compat=1 /* DPL1 gate, restricted to 32bit PV guests only. */
+ CR4_PV32_RESTORE
+
+ cmpb $0,untrusted_msi(%rip)
+@@ -127,7 +128,6 @@ compat_test_guest_events:
+ /* %rbx: struct vcpu */
+ compat_process_softirqs:
+ sti
+- andl $~TRAP_regs_partial,UREGS_entry_vector(%rsp)
+ call do_softirq
+ jmp compat_test_all_events
+
+@@ -268,7 +268,8 @@ ENTRY(cstar_enter)
+ pushq $FLAT_USER_CS32
+ pushq %rcx
+ pushq $0
+- SAVE_VOLATILE TRAP_syscall
++ movl $TRAP_syscall, 4(%rsp)
++ SAVE_ALL
+ GET_CURRENT(bx)
+ movq VCPU_domain(%rbx),%rcx
+ cmpb $0,DOMAIN_is_32bit_pv(%rcx)
+diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
+index 708d9b9402..cebb1e4f4f 100644
+--- a/xen/arch/x86/x86_64/entry.S
++++ b/xen/arch/x86/x86_64/entry.S
+@@ -97,7 +97,8 @@ ENTRY(lstar_enter)
+ pushq $FLAT_KERNEL_CS64
+ pushq %rcx
+ pushq $0
+- SAVE_VOLATILE TRAP_syscall
++ movl $TRAP_syscall, 4(%rsp)
++ SAVE_ALL
+ GET_CURRENT(bx)
+ testb $TF_kernel_mode,VCPU_thread_flags(%rbx)
+ jz switch_to_kernel
+@@ -192,7 +193,6 @@ test_guest_events:
+ /* %rbx: struct vcpu */
+ process_softirqs:
+ sti
+- SAVE_PRESERVED
+ call do_softirq
+ jmp test_all_events
+
+@@ -246,7 +246,8 @@ GLOBAL(sysenter_eflags_saved)
+ pushq $3 /* ring 3 null cs */
+ pushq $0 /* null rip */
+ pushq $0
+- SAVE_VOLATILE TRAP_syscall
++ movl $TRAP_syscall, 4(%rsp)
++ SAVE_ALL
+ GET_CURRENT(bx)
+ cmpb $0,VCPU_sysenter_disables_events(%rbx)
+ movq VCPU_sysenter_addr(%rbx),%rax
+@@ -263,7 +264,6 @@ UNLIKELY_END(sysenter_nt_set)
+ leal (,%rcx,TBF_INTERRUPT),%ecx
+ UNLIKELY_START(z, sysenter_gpf)
+ movq VCPU_trap_ctxt(%rbx),%rsi
+- SAVE_PRESERVED
+ movl $TRAP_gp_fault,UREGS_entry_vector(%rsp)
+ movl %eax,TRAPBOUNCE_error_code(%rdx)
+ movq TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_eip(%rsi),%rax
+@@ -281,7 +281,8 @@ UNLIKELY_END(sysenter_gpf)
+ ENTRY(int80_direct_trap)
+ ASM_CLAC
+ pushq $0
+- SAVE_VOLATILE 0x80
++ movl $0x80, 4(%rsp)
++ SAVE_ALL
+
+ cmpb $0,untrusted_msi(%rip)
+ UNLIKELY_START(ne, msi_check)
+@@ -309,7 +310,6 @@ int80_slow_path:
+ * IDT entry with DPL==0.
+ */
+ movl $((0x80 << 3) | X86_XEC_IDT),UREGS_error_code(%rsp)
+- SAVE_PRESERVED
+ movl $TRAP_gp_fault,UREGS_entry_vector(%rsp)
+ /* A GPF wouldn't have incremented the instruction pointer. */
+ subq $2,UREGS_rip(%rsp)
+diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
+index 22816100fd..bf8dfcbdee 100644
+--- a/xen/arch/x86/x86_64/traps.c
++++ b/xen/arch/x86/x86_64/traps.c
+@@ -81,15 +81,10 @@ static void _show_registers(
+ regs->rbp, regs->rsp, regs->r8);
+ printk("r9: %016lx r10: %016lx r11: %016lx\n",
+ regs->r9, regs->r10, regs->r11);
+- if ( !(regs->entry_vector & TRAP_regs_partial) )
+- {
+- printk("r12: %016lx r13: %016lx r14: %016lx\n",
+- regs->r12, regs->r13, regs->r14);
+- printk("r15: %016lx cr0: %016lx cr4: %016lx\n",
+- regs->r15, crs[0], crs[4]);
+- }
+- else
+- printk("cr0: %016lx cr4: %016lx\n", crs[0], crs[4]);
++ printk("r12: %016lx r13: %016lx r14: %016lx\n",
++ regs->r12, regs->r13, regs->r14);
++ printk("r15: %016lx cr0: %016lx cr4: %016lx\n",
++ regs->r15, crs[0], crs[4]);
+ printk("cr3: %016lx cr2: %016lx\n", crs[3], crs[2]);
+ printk("fsb: %016lx gsb: %016lx gss: %016lx\n",
+ crs[5], crs[6], crs[7]);
+diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c
+index 28132b5dbc..43730026c2 100644
+--- a/xen/arch/x86/x86_emulate.c
++++ b/xen/arch/x86/x86_emulate.c
+@@ -11,7 +11,6 @@
+
+ #include <xen/domain_page.h>
+ #include <asm/x86_emulate.h>
+-#include <asm/asm_defns.h> /* mark_regs_dirty() */
+ #include <asm/processor.h> /* current_cpu_info */
+ #include <asm/amd.h> /* cpu_has_amd_erratum() */
+
+diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c
+index 4ee3df9247..fcfe9f7de7 100644
+--- a/xen/arch/x86/x86_emulate/x86_emulate.c
++++ b/xen/arch/x86/x86_emulate/x86_emulate.c
+@@ -1424,10 +1424,10 @@ decode_register(
+ case 9: p = &regs->r9; break;
+ case 10: p = &regs->r10; break;
+ case 11: p = &regs->r11; break;
+- case 12: mark_regs_dirty(regs); p = &regs->r12; break;
+- case 13: mark_regs_dirty(regs); p = &regs->r13; break;
+- case 14: mark_regs_dirty(regs); p = &regs->r14; break;
+- case 15: mark_regs_dirty(regs); p = &regs->r15; break;
++ case 12: p = &regs->r12; break;
++ case 13: p = &regs->r13; break;
++ case 14: p = &regs->r14; break;
++ case 15: p = &regs->r15; break;
+ #endif
+ default: BUG(); p = NULL; break;
+ }
+diff --git a/xen/common/wait.c b/xen/common/wait.c
+index 4ac98c07fe..398f653174 100644
+--- a/xen/common/wait.c
++++ b/xen/common/wait.c
+@@ -128,7 +128,6 @@ static void __prepare_to_wait(struct waitqueue_vcpu *wqv)
+ unsigned long dummy;
+ u32 entry_vector = cpu_info->guest_cpu_user_regs.entry_vector;
+
+- cpu_info->guest_cpu_user_regs.entry_vector &= ~TRAP_regs_partial;
+ ASSERT(wqv->esp == 0);
+
+ /* Save current VCPU affinity; force wakeup on *this* CPU only. */
+diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h
+index 279d70298f..6e5c079ad8 100644
+--- a/xen/include/asm-x86/asm_defns.h
++++ b/xen/include/asm-x86/asm_defns.h
+@@ -17,15 +17,6 @@
+ void ret_from_intr(void);
+ #endif
+
+-#ifdef CONFIG_FRAME_POINTER
+-/* Indicate special exception stack frame by inverting the frame pointer. */
+-#define SETUP_EXCEPTION_FRAME_POINTER(offs) \
+- leaq offs(%rsp),%rbp; \
+- notq %rbp
+-#else
+-#define SETUP_EXCEPTION_FRAME_POINTER(offs)
+-#endif
+-
+ #ifndef NDEBUG
+ #define ASSERT_INTERRUPT_STATUS(x, msg) \
+ pushf; \
+@@ -42,31 +33,6 @@ void ret_from_intr(void);
+ #define ASSERT_INTERRUPTS_DISABLED \
+ ASSERT_INTERRUPT_STATUS(z, "INTERRUPTS DISABLED")
+
+-/*
+- * This flag is set in an exception frame when registers R12-R15 did not get
+- * saved.
+- */
+-#define _TRAP_regs_partial 16
+-#define TRAP_regs_partial (1 << _TRAP_regs_partial)
+-/*
+- * This flag gets set in an exception frame when registers R12-R15 possibly
+- * get modified from their originally saved values and hence need to be
+- * restored even if the normal call flow would restore register values.
+- *
+- * The flag being set implies _TRAP_regs_partial to be unset. Restoring
+- * R12-R15 thus is
+- * - required when this flag is set,
+- * - safe when _TRAP_regs_partial is unset.
+- */
+-#define _TRAP_regs_dirty 17
+-#define TRAP_regs_dirty (1 << _TRAP_regs_dirty)
+-
+-#define mark_regs_dirty(r) ({ \
+- struct cpu_user_regs *r__ = (r); \
+- ASSERT(!((r__)->entry_vector & TRAP_regs_partial)); \
+- r__->entry_vector |= TRAP_regs_dirty; \
+-})
+-
+ #ifdef __ASSEMBLY__
+ # define _ASM_EX(p) p-.
+ #else
+@@ -236,7 +202,7 @@ static always_inline void stac(void)
+ #endif
+
+ #ifdef __ASSEMBLY__
+-.macro SAVE_ALL op
++.macro SAVE_ALL op, compat=0
+ .ifeqs "\op", "CLAC"
+ ASM_CLAC
+ .else
+@@ -255,40 +221,6 @@ static always_inline void stac(void)
+ movq %rdx,UREGS_rdx(%rsp)
+ movq %rcx,UREGS_rcx(%rsp)
+ movq %rax,UREGS_rax(%rsp)
+- movq %r8,UREGS_r8(%rsp)
+- movq %r9,UREGS_r9(%rsp)
+- movq %r10,UREGS_r10(%rsp)
+- movq %r11,UREGS_r11(%rsp)
+- movq %rbx,UREGS_rbx(%rsp)
+- movq %rbp,UREGS_rbp(%rsp)
+- SETUP_EXCEPTION_FRAME_POINTER(UREGS_rbp)
+- movq %r12,UREGS_r12(%rsp)
+- movq %r13,UREGS_r13(%rsp)
+- movq %r14,UREGS_r14(%rsp)
+- movq %r15,UREGS_r15(%rsp)
+-.endm
+-
+-/*
+- * Save all registers not preserved by C code or used in entry/exit code. Mark
+- * the frame as partial.
+- *
+- * @type: exception type
+- * @compat: R8-R15 don't need saving, and the frame nevertheless is complete
+- */
+-.macro SAVE_VOLATILE type compat=0
+-.if \compat
+- movl $\type,UREGS_entry_vector-UREGS_error_code(%rsp)
+-.else
+- movl $\type|TRAP_regs_partial,\
+- UREGS_entry_vector-UREGS_error_code(%rsp)
+-.endif
+- addq $-(UREGS_error_code-UREGS_r15),%rsp
+- cld
+- movq %rdi,UREGS_rdi(%rsp)
+- movq %rsi,UREGS_rsi(%rsp)
+- movq %rdx,UREGS_rdx(%rsp)
+- movq %rcx,UREGS_rcx(%rsp)
+- movq %rax,UREGS_rax(%rsp)
+ .if !\compat
+ movq %r8,UREGS_r8(%rsp)
+ movq %r9,UREGS_r9(%rsp)
+@@ -297,20 +229,17 @@ static always_inline void stac(void)
+ .endif
+ movq %rbx,UREGS_rbx(%rsp)
+ movq %rbp,UREGS_rbp(%rsp)
+- SETUP_EXCEPTION_FRAME_POINTER(UREGS_rbp)
+-.endm
+-
+-/*
+- * Complete a frame potentially only partially saved.
+- */
+-.macro SAVE_PRESERVED
+- btrl $_TRAP_regs_partial,UREGS_entry_vector(%rsp)
+- jnc 987f
++#ifdef CONFIG_FRAME_POINTER
++/* Indicate special exception stack frame by inverting the frame pointer. */
++ leaq UREGS_rbp(%rsp), %rbp
++ notq %rbp
++#endif
++.if !\compat
+ movq %r12,UREGS_r12(%rsp)
+ movq %r13,UREGS_r13(%rsp)
+ movq %r14,UREGS_r14(%rsp)
+ movq %r15,UREGS_r15(%rsp)
+-987:
++.endif
+ .endm
+
+ #define LOAD_ONE_REG(reg, compat) \
+@@ -351,33 +280,13 @@ static always_inline void stac(void)
+ * @compat: R8-R15 don't need reloading
+ */
+ .macro RESTORE_ALL adj=0 compat=0
+-.if !\compat
+- testl $TRAP_regs_dirty,UREGS_entry_vector(%rsp)
+-.endif
+ LOAD_C_CLOBBERED \compat
+ .if !\compat
+- jz 987f
+ movq UREGS_r15(%rsp),%r15
+ movq UREGS_r14(%rsp),%r14
+ movq UREGS_r13(%rsp),%r13
+ movq UREGS_r12(%rsp),%r12
+-#ifndef NDEBUG
+- .subsection 1
+-987: testl $TRAP_regs_partial,UREGS_entry_vector(%rsp)
+- jnz 987f
+- cmpq UREGS_r15(%rsp),%r15
+- jne 789f
+- cmpq UREGS_r14(%rsp),%r14
+- jne 789f
+- cmpq UREGS_r13(%rsp),%r13
+- jne 789f
+- cmpq UREGS_r12(%rsp),%r12
+- je 987f
+-789: BUG /* Corruption of partial register state. */
+- .subsection 0
+-#endif
+ .endif
+-987:
+ LOAD_ONE_REG(bp, \compat)
+ LOAD_ONE_REG(bx, \compat)
+ subq $-(UREGS_error_code-UREGS_r15+\adj), %rsp
+--
+2.15.1
+
diff --git a/emulators/xen-kernel/files/0001-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch b/emulators/xen-kernel/files/0001-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch
new file mode 100644
index 000000000000..47a12b33787e
--- /dev/null
+++ b/emulators/xen-kernel/files/0001-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch
@@ -0,0 +1,45 @@
+From 9b76908e6e074d7efbeafe6bad066ecc5f3c3c43 Mon Sep 17 00:00:00 2001
+From: Andrew Cooper <andrew.cooper3@citrix.com>
+Date: Wed, 17 Jan 2018 17:23:37 +0100
+Subject: [PATCH] x86/mm: Always set _PAGE_ACCESSED on L4e updates
+
+Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
+Reviewed-by: Jan Beulich <jbeulich@suse.com>
+master commit: bd61fe94bee0556bc2f64999a4a8315b93f90f21
+master date: 2018-01-15 13:53:16 +0000
+---
+ xen/arch/x86/mm.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
+index ada12c05c5..50f500c940 100644
+--- a/xen/arch/x86/mm.c
++++ b/xen/arch/x86/mm.c
+@@ -1296,11 +1296,23 @@ get_page_from_l4e(
+ _PAGE_USER|_PAGE_RW); \
+ } while ( 0 )
+
++/*
++ * When shadowing an L4 behind the guests back (e.g. for per-pcpu
++ * purposes), we cannot efficiently sync access bit updates from hardware
++ * (on the shadow tables) back into the guest view.
++ *
++ * We therefore unconditionally set _PAGE_ACCESSED even in the guests
++ * view. This will appear to the guest as a CPU which proactively pulls
++ * all valid L4e's into its TLB, which is compatible with the x86 ABI.
++ *
++ * At the time of writing, all PV guests set the access bit anyway, so
++ * this is no actual change in their behaviour.
++ */
+ #define adjust_guest_l4e(pl4e, d) \
+ do { \
+ if ( likely(l4e_get_flags((pl4e)) & _PAGE_PRESENT) && \
+ likely(!is_pv_32bit_domain(d)) ) \
+- l4e_add_flags((pl4e), _PAGE_USER); \
++ l4e_add_flags((pl4e), _PAGE_USER | _PAGE_ACCESSED); \
+ } while ( 0 )
+
+ #define unadjust_guest_l3e(pl3e, d) \
+--
+2.15.1
+