diff options
Diffstat (limited to 'main/xen')
-rw-r--r-- | main/xen/0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch | 409 | ||||
-rw-r--r-- | main/xen/0002-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch | 46 | ||||
-rw-r--r-- | main/xen/0004-x86-allow-Meltdown-band-aid-to-be-disabled.patch | 164 | ||||
-rw-r--r-- | main/xen/APKBUILD | 47 | ||||
-rw-r--r-- | main/xen/xsa246-4.9.patch | 74 | ||||
-rw-r--r-- | main/xen/xsa247-4.9-1.patch | 176 | ||||
-rw-r--r-- | main/xen/xsa248.patch | 164 | ||||
-rw-r--r-- | main/xen/xsa249.patch | 42 | ||||
-rw-r--r-- | main/xen/xsa250.patch | 67 | ||||
-rw-r--r-- | main/xen/xsa251.patch | 21 | ||||
-rw-r--r-- | main/xen/xsa253-4.10.patch | 26 | ||||
-rw-r--r-- | main/xen/xsa254-4.10.patch (renamed from main/xen/0003-x86-Meltdown-band-aid-against-malicious-64-bit-PV-gu.patch) | 702 |
12 files changed, 695 insertions, 1243 deletions
diff --git a/main/xen/0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch b/main/xen/0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch deleted file mode 100644 index 749306b6d5..0000000000 --- a/main/xen/0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch +++ /dev/null @@ -1,409 +0,0 @@ -From c60e88d20d08253904d582478b50d2eebbef1fb6 Mon Sep 17 00:00:00 2001 -From: Andrew Cooper <andrew.cooper3@citrix.com> -Date: Wed, 17 Jan 2018 17:03:51 +0100 -Subject: [PATCH 1/4] 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 -(cherry picked from commit 2213ffe1a2d82c3c9c4a154ea6ee252395aa8693) ---- - 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 | 105 +++------------------------------ - 10 files changed, 26 insertions(+), 125 deletions(-) - -diff --git a/tools/tests/x86_emulator/x86_emulate.c b/tools/tests/x86_emulator/x86_emulate.c -index 79661d5c2b..b10ca2cfc9 100644 ---- a/tools/tests/x86_emulator/x86_emulate.c -+++ b/tools/tests/x86_emulator/x86_emulate.c -@@ -3,7 +3,6 @@ - #include <sys/mman.h> - - #define cpu_has_amd_erratum(nr) 0 --#define mark_regs_dirty(r) ((void)(r)) - #define cpu_has_mpx false - #define read_bndcfgu() 0 - #define xstate_set_init(what) -diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c -index 765bc0085d..07b50315b9 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 e861f7af66..3aef0f2769 100644 ---- a/xen/arch/x86/traps.c -+++ b/xen/arch/x86/traps.c -@@ -2204,7 +2204,6 @@ static int priv_op_read_io(unsigned int port, unsigned int bytes, - io_emul_stub_t *io_emul = - io_emul_stub_setup(poc, ctxt->opcode, port, bytes); - -- mark_regs_dirty(ctxt->regs); - io_emul(ctxt->regs); - return X86EMUL_DONE; - } -@@ -2234,7 +2233,6 @@ static int priv_op_write_io(unsigned int port, unsigned int bytes, - io_emul_stub_t *io_emul = - io_emul_stub_setup(poc, ctxt->opcode, port, bytes); - -- mark_regs_dirty(ctxt->regs); - io_emul(ctxt->regs); - if ( (bytes == 1) && pv_post_outb_hook ) - pv_post_outb_hook(port, val); -diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S -index 90bda09614..37864a67f3 100644 ---- a/xen/arch/x86/x86_64/compat/entry.S -+++ b/xen/arch/x86/x86_64/compat/entry.S -@@ -14,7 +14,8 @@ - ENTRY(entry_int82) - ASM_CLAC - pushq $0 -- SAVE_VOLATILE type=HYPERCALL_VECTOR compat=1 -+ movl $HYPERCALL_VECTOR, 4(%rsp) -+ SAVE_ALL compat=1 /* DPL1 gate, restricted to 32bit PV guests only. */ - CR4_PV32_RESTORE - - GET_CURRENT(bx) -@@ -58,7 +59,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 - -@@ -195,7 +195,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 65c771f979..668bf8ac28 100644 ---- a/xen/arch/x86/x86_64/entry.S -+++ b/xen/arch/x86/x86_64/entry.S -@@ -96,7 +96,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 -@@ -138,7 +139,6 @@ test_guest_events: - /* %rbx: struct vcpu */ - process_softirqs: - sti -- SAVE_PRESERVED - call do_softirq - jmp test_all_events - -@@ -188,7 +188,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 -@@ -205,7 +206,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 -@@ -223,7 +223,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) -@@ -251,7 +252,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 fb42158070..4f92a2e1ca 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 cc334ca8f9..c7ba221d11 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/xstate.h> - #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 5ef14a9c72..f20481a611 100644 ---- a/xen/arch/x86/x86_emulate/x86_emulate.c -+++ b/xen/arch/x86/x86_emulate/x86_emulate.c -@@ -1937,10 +1937,10 @@ decode_register( - case 9: p = ®s->r9; break; - case 10: p = ®s->r10; break; - case 11: p = ®s->r11; break; -- case 12: mark_regs_dirty(regs); p = ®s->r12; break; -- case 13: mark_regs_dirty(regs); p = ®s->r13; break; -- case 14: mark_regs_dirty(regs); p = ®s->r14; break; -- case 15: mark_regs_dirty(regs); p = ®s->r15; break; -+ case 12: p = ®s->r12; break; -+ case 13: p = ®s->r13; break; -+ case 14: p = ®s->r14; break; -+ case 15: p = ®s->r15; break; - #endif - default: BUG(); p = NULL; break; - } -diff --git a/xen/common/wait.c b/xen/common/wait.c -index 9490a17dc2..c5fc094e2c 100644 ---- a/xen/common/wait.c -+++ b/xen/common/wait.c -@@ -127,7 +127,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 388fc93b9d..98192eb4e6 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) \ -@@ -330,7 +259,6 @@ static always_inline void stac(void) - */ - .macro RESTORE_ALL adj=0 compat=0 - .if !\compat -- testl $TRAP_regs_dirty,UREGS_entry_vector(%rsp) - movq UREGS_r11(%rsp),%r11 - movq UREGS_r10(%rsp),%r10 - movq UREGS_r9(%rsp),%r9 -@@ -347,33 +275,16 @@ static always_inline void stac(void) - LOAD_ONE_REG(si, \compat) - LOAD_ONE_REG(di, \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 - .else - xor %r15, %r15 - xor %r14, %r14 - xor %r13, %r13 - xor %r12, %r12 - .endif --987: - LOAD_ONE_REG(bp, \compat) - LOAD_ONE_REG(bx, \compat) - subq $-(UREGS_error_code-UREGS_r15+\adj), %rsp --- -2.15.0 - diff --git a/main/xen/0002-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch b/main/xen/0002-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch deleted file mode 100644 index 232260bb36..0000000000 --- a/main/xen/0002-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 344da8f57f442be289bb3c09defb28758b227542 Mon Sep 17 00:00:00 2001 -From: Andrew Cooper <andrew.cooper3@citrix.com> -Date: Wed, 17 Jan 2018 17:04:59 +0100 -Subject: [PATCH 2/4] 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 -(cherry picked from commit 87ea7816247090e8e5bc5653b16c412943a058b5) ---- - 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 e77574f92b..981458907f 100644 ---- a/xen/arch/x86/mm.c -+++ b/xen/arch/x86/mm.c -@@ -1322,11 +1322,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.0 - diff --git a/main/xen/0004-x86-allow-Meltdown-band-aid-to-be-disabled.patch b/main/xen/0004-x86-allow-Meltdown-band-aid-to-be-disabled.patch deleted file mode 100644 index d8bcd3a0b0..0000000000 --- a/main/xen/0004-x86-allow-Meltdown-band-aid-to-be-disabled.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 5ab23f2997a50f2f66acef6437ca50df35a32bb6 Mon Sep 17 00:00:00 2001 -From: Jan Beulich <jbeulich@suse.com> -Date: Wed, 17 Jan 2018 17:08:25 +0100 -Subject: [PATCH 4/4] x86: allow Meltdown band-aid to be disabled - -First of all we don't need it on AMD systems. Additionally allow its use -to be controlled by command line option. For best backportability, this -intentionally doesn't use alternative instruction patching to achieve -the intended effect - while we likely want it, this will be later -follow-up. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> -master commit: e871e80c38547d9faefc6604532ba3e985e65873 -master date: 2018-01-16 17:50:59 +0100 -(cherry picked from commit dc7d46580d9c633a59be1c3776f79c01dd0cb98b) ---- - docs/misc/xen-command-line.markdown | 12 ++++++++++++ - xen/arch/x86/domain.c | 7 +++++-- - xen/arch/x86/mm.c | 2 +- - xen/arch/x86/smpboot.c | 17 ++++++++++++++--- - xen/arch/x86/x86_64/entry.S | 2 ++ - 5 files changed, 34 insertions(+), 6 deletions(-) - -diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown -index 0202b1643d..587cdb9196 100644 ---- a/docs/misc/xen-command-line.markdown -+++ b/docs/misc/xen-command-line.markdown -@@ -1791,6 +1791,18 @@ In the case that x2apic is in use, this option switches between physical and - clustered mode. The default, given no hint from the **FADT**, is cluster - mode. - -+### xpti -+> `= <boolean>` -+ -+> Default: `false` on AMD hardware -+> Default: `true` everywhere else -+ -+Override default selection of whether to isolate 64-bit PV guest page -+tables. -+ -+** WARNING: Not yet a complete isolation implementation, but better than -+nothing. ** -+ - ### xsave - > `= <boolean>` - -diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c -index c0f0fc7a32..069c314ee5 100644 ---- a/xen/arch/x86/domain.c -+++ b/xen/arch/x86/domain.c -@@ -1929,12 +1929,15 @@ static void paravirt_ctxt_switch_from(struct vcpu *v) - - static void paravirt_ctxt_switch_to(struct vcpu *v) - { -+ root_pgentry_t *root_pgt = this_cpu(root_pgt); - unsigned long cr4; - - switch_kernel_stack(v); - -- this_cpu(root_pgt)[root_table_offset(PERDOMAIN_VIRT_START)] = -- l4e_from_page(v->domain->arch.perdomain_l3_pg, __PAGE_HYPERVISOR_RW); -+ if ( root_pgt ) -+ root_pgt[root_table_offset(PERDOMAIN_VIRT_START)] = -+ l4e_from_page(v->domain->arch.perdomain_l3_pg, -+ __PAGE_HYPERVISOR_RW); - - cr4 = pv_guest_cr4_to_real_cr4(v); - if ( unlikely(cr4 != read_cr4()) ) -diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c -index 78f4cb37f5..2f38a6c195 100644 ---- a/xen/arch/x86/mm.c -+++ b/xen/arch/x86/mm.c -@@ -4056,7 +4056,7 @@ long do_mmu_update( - rc = mod_l4_entry(va, l4e_from_intpte(req.val), mfn, - cmd == MMU_PT_UPDATE_PRESERVE_AD, v); - if ( !rc ) -- sync_guest = true; -+ sync_guest = this_cpu(root_pgt); - break; - case PGT_writable_page: - perfc_incr(writable_mmu_updates); -diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c -index 965a49f923..bb033684ef 100644 ---- a/xen/arch/x86/smpboot.c -+++ b/xen/arch/x86/smpboot.c -@@ -322,7 +322,7 @@ void start_secondary(void *unused) - spin_debug_disable(); - - get_cpu_info()->xen_cr3 = 0; -- get_cpu_info()->pv_cr3 = __pa(this_cpu(root_pgt)); -+ get_cpu_info()->pv_cr3 = this_cpu(root_pgt) ? __pa(this_cpu(root_pgt)) : 0; - - load_system_tables(); - -@@ -736,14 +736,20 @@ static int clone_mapping(const void *ptr, root_pgentry_t *rpt) - return 0; - } - -+static __read_mostly int8_t opt_xpti = -1; -+boolean_param("xpti", opt_xpti); - DEFINE_PER_CPU(root_pgentry_t *, root_pgt); - - static int setup_cpu_root_pgt(unsigned int cpu) - { -- root_pgentry_t *rpt = alloc_xen_pagetable(); -+ root_pgentry_t *rpt; - unsigned int off; - int rc; - -+ if ( !opt_xpti ) -+ return 0; -+ -+ rpt = alloc_xen_pagetable(); - if ( !rpt ) - return -ENOMEM; - -@@ -987,10 +993,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) - - stack_base[0] = stack_start; - -+ if ( opt_xpti < 0 ) -+ opt_xpti = boot_cpu_data.x86_vendor != X86_VENDOR_AMD; -+ - rc = setup_cpu_root_pgt(0); - if ( rc ) - panic("Error %d setting up PV root page table\n", rc); -- get_cpu_info()->pv_cr3 = __pa(per_cpu(root_pgt, 0)); -+ if ( per_cpu(root_pgt, 0) ) -+ get_cpu_info()->pv_cr3 = __pa(per_cpu(root_pgt, 0)); - - set_nr_sockets(); - -@@ -1063,6 +1073,7 @@ void __init smp_prepare_boot_cpu(void) - #endif - - get_cpu_info()->xen_cr3 = 0; -+ get_cpu_info()->pv_cr3 = 0; - } - - static void -diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S -index 16cf095ee1..5f9ce2d6b7 100644 ---- a/xen/arch/x86/x86_64/entry.S -+++ b/xen/arch/x86/x86_64/entry.S -@@ -44,6 +44,7 @@ restore_all_guest: - movabs $DIRECTMAP_VIRT_START, %rcx - mov %rdi, %rax - and %rsi, %rdi -+ jz .Lrag_keep_cr3 - and %r9, %rsi - add %rcx, %rdi - add %rcx, %rsi -@@ -60,6 +61,7 @@ restore_all_guest: - rep movsq - mov %r9, STACK_CPUINFO_FIELD(xen_cr3)(%rdx) - write_cr3 rax, rdi, rsi -+.Lrag_keep_cr3: - - RESTORE_ALL - testw $TRAP_syscall,4(%rsp) --- -2.15.0 - diff --git a/main/xen/APKBUILD b/main/xen/APKBUILD index b05d25d32d..72dace8262 100644 --- a/main/xen/APKBUILD +++ b/main/xen/APKBUILD @@ -2,8 +2,8 @@ # Contributor: Roger Pau Monne <roger.pau@entel.upc.edu> # Maintainer: William Pitcock <nenolod@dereferenced.org> pkgname=xen -pkgver=4.9.1 -pkgrel=3 +pkgver=4.10.0 +pkgrel=0 pkgdesc="Xen hypervisor" url="http://www.xen.org/" arch="x86_64 armhf aarch64" @@ -101,13 +101,13 @@ options="!strip" # 4.9.1-r1: # - XSA-246 # - XSA-247 -# 4.9.1-r2: -# - XSA-254 XPTI -# 4.9.1-r3: +# 4.10.0-r1: # - XSA-248 # - XSA-249 # - XSA-250 # - XSA-251 +# - XSA-253 +# - XSA-254 case "$CARCH" in x86*) @@ -142,7 +142,7 @@ _POLARSSL_VERSION="1.1.4" _TPMEMU_VERSION="0.7.4" # grep ^IPXE_GIT_TAG tools/firmware/etherboot/Makefile -_IPXE_GIT_TAG=827dd1bfee67daa683935ce65316f7e0f057fe1c +_IPXE_GIT_TAG=356f6c1b64d7a97746d1816cef8ca22bdd8d0b5d source="https://downloads.xenproject.org/release/$pkgname/$pkgver/$pkgname-$pkgver.tar.gz http://xenbits.xen.org/xen-extfiles/gmp-$_GMP_VERSION.tar.bz2 @@ -155,25 +155,13 @@ source="https://downloads.xenproject.org/release/$pkgname/$pkgver/$pkgname-$pkgv http://xenbits.xen.org/xen-extfiles/zlib-$_ZLIB_VERSION.tar.gz http://xenbits.xen.org/xen-extfiles/ipxe-git-$_IPXE_GIT_TAG.tar.gz - xsa246-4.9.patch - xsa247-4.9-1.patch - xsa247-4.9-2.patch - xsa248.patch - xsa249.patch - xsa250.patch - xsa251.patch + xsa253-4.10.patch + xsa254-4.10.patch - 0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch - 0002-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch - 0003-x86-Meltdown-band-aid-against-malicious-64-bit-PV-gu.patch - 0004-x86-allow-Meltdown-band-aid-to-be-disabled.patch - - qemu-coroutine-gthread.patch qemu-xen_paths.patch hotplug-vif-vtrill.patch - musl-support.patch musl-hvmloader-fix-stdint.patch stdint_local.h elf_local.h @@ -416,7 +404,7 @@ EOF } -sha512sums="9d22f0aa5dcd01a1c105d17c14bce570cc597e884ddb9b4a46b80a72f647625b76ae5213cede423d0458c14e1906983595a9269bb6e6ff2e9e7e4dea840f4274 xen-4.9.1.tar.gz +sha512sums="5a37935c382f9cfe3641a35c3be0ba11689bca10c7d3c2401963513e3a834ee8d0c8a0ddcf3716dbf0a795aea1bab78caf19acf1272e5e054bf012cfa06a4690 xen-4.10.0.tar.gz 2e0b0fd23e6f10742a5517981e5171c6e88b0a93c83da701b296f5c0861d72c19782daab589a7eac3f9032152a0fc7eff7f5362db8fccc4859564a9aa82329cf gmp-4.3.2.tar.bz2 c2bc9ffc8583aeae71cee9ddcc4418969768d4e3764d47307da54f93981c0109fb07d84b061b3a3628bd00ba4d14a54742bc04848110eb3ae8ca25dbfbaabadb grub-0.97.tar.gz 1465b58279af1647f909450e394fe002ca165f0ff4a0254bfa9fe0e64316f50facdde2729d79a4e632565b4500cf4d6c74192ac0dd3bc9fe09129bbd67ba089d lwip-1.3.0.tar.gz @@ -425,22 +413,11 @@ c2bc9ffc8583aeae71cee9ddcc4418969768d4e3764d47307da54f93981c0109fb07d84b061b3a36 88da614e4d3f4409c4fd3bb3e44c7587ba051e3fed4e33d526069a67e8180212e1ea22da984656f50e290049f60ddca65383e5983c0f8884f648d71f698303ad polarssl-1.1.4-gpl.tgz 4928b5b82f57645be9408362706ff2c4d9baa635b21b0d41b1c82930e8c60a759b1ea4fa74d7e6c7cae1b7692d006aa5cb72df0c3b88bf049779aa2b566f9d35 tpm_emulator-0.7.4.tar.gz 021b958fcd0d346c4ba761bcf0cc40f3522de6186cf5a0a6ea34a70504ce9622b1c2626fce40675bc8282cf5f5ade18473656abc38050f72f5d6480507a2106e zlib-1.2.3.tar.gz -82ba65e1c676d32b29c71e6395c9506cab952c8f8b03f692e2b50133be8f0c0146d0f22c223262d81a4df579986fde5abc6507869f4965be4846297ef7b4b890 ipxe-git-827dd1bfee67daa683935ce65316f7e0f057fe1c.tar.gz -b00f42d2069f273e204698177d2c36950cee759a92dfe7833c812ddff4dedde2c4a842980927ec4fc46d1f54b49879bf3a3681c6faf30b72fb3ad6a7eba060b2 xsa246-4.9.patch -c5e064543048751fda86ce64587493518da87d219ff077abb83ac13d8381ceb29f1b6479fc0b761b8f7a04c8c70203791ac4a8cc79bbc6f4dcfa6661c4790c5e xsa247-4.9-1.patch -71aefbe27cbd1d1d363b7d5826c69a238e4aad2958a1c6da330ae5daee791f54ce1d01fb79db84ed4248ab8b1593c9c28c3de5108f4d0953b04f7819af23a1d1 xsa247-4.9-2.patch -6415689190b8f4ead7a3482a2285485af4acd4f3565521736f8fe975c74c7c70b27608e0142a7165b4f735b547b688db99a6027697e77b3e1d15c09e14b4f0a6 xsa248.patch -05a2e954bab1877500eb5ed3a8c49edb27411ed3ec9dbfb2115b7804a3b03c6d45c9f08a7ed96ff2b586346f321142065a8c5a5d996468496b373637b6ee31b9 xsa249.patch -b3030f09ddb4f9e4a356519c7b74d393e8db085278a1e616788c81d19988699a6efdd8568277c25514f3298ca92e5a09e3cd08b0a308a4d2ddb55374a8445657 xsa250.patch -928153b48af2bd6b334058c5919880cfc7d665c63e0232932866941cbea6deb8d0d83f70dff0974d3df27fc84096beca51139a0b1c0585978f298256b3fd82eb xsa251.patch -cda45e5a564e429a1299f07ea496b0e0614f6b2d71a5dcd24f5efdb571cc54d74d04c8e0766279fe2acb7d9bb9cf8505281d6c7ba2d6334009e14a10f83096ee 0001-x86-entry-Remove-support-for-partial-cpu_user_regs-f.patch -bce07e4094ae3036dafdf9fe3aeb1f566281484e1398184d774af9ad371066c0e8af232b8d1ab5d450923fb482e6dea6dfb921976b87b20ab56a3f2b4486d0d4 0002-x86-mm-Always-set-_PAGE_ACCESSED-on-L4e-updates.patch -ba09c54451fae35f3fc70e4f2a76791bc652ad373e87402ebc30c53f8e7db2368d52a9018cc28a5efcbcd77e85c9ae45d9580550f215a3f9bbf63bbd21ef938d 0003-x86-Meltdown-band-aid-against-malicious-64-bit-PV-gu.patch -ff100f19972d55acae495752a05f5ad834819a4fb1a03547d8167a635ed5076b5ae923f57087ce3568f285718dd78149e2987cf811105906c9b45965878aba72 0004-x86-allow-Meltdown-band-aid-to-be-disabled.patch -c3c46f232f0bd9f767b232af7e8ce910a6166b126bd5427bb8dc325aeb2c634b956de3fc225cab5af72649070c8205cc8e1cab7689fc266c204f525086f1a562 qemu-coroutine-gthread.patch +bbcce5e55040e7e29adebd4a5253a046016a6e2e7ff34cf801a42d147e1ec1af57e0297318249bfa9c5bbeac969fe4b37c18cbf845a80b2136d65387a4fc31da ipxe-git-356f6c1b64d7a97746d1816cef8ca22bdd8d0b5d.tar.gz +58f288fb3087ecdd42075031b5604a493adef0754f68d596dce8576fbc46bfe8b1bf3dc429269cab3797b6f193036bdafeb32cf2c7cca34d9c89d5fe95a0453c xsa253-4.10.patch +f15350c0b44d3a6d5a3056dfac81d25f2af047135c528f6258f3d42ef26e6d87511d8e148a63e8d7d88108e07dc5b3551ed54c915be6dc3fe3f978ab72094321 xsa254-4.10.patch 1936ab39a1867957fa640eb81c4070214ca4856a2743ba7e49c0cd017917071a9680d015f002c57fa7b9600dbadd29dcea5887f50e6c133305df2669a7a933f3 qemu-xen_paths.patch f095ea373f36381491ad36f0662fb4f53665031973721256b23166e596318581da7cbb0146d0beb2446729adfdb321e01468e377793f6563a67d68b8b0f7ffe3 hotplug-vif-vtrill.patch -e635cf27ca022ca5bc829e089b5e9a3ce9e566d4701d06bc38a22e356de45a71bc33e170d6db333d4efe8389144419cc27834a2eee0bcae9118d4ca9aff64306 musl-support.patch 77b08e9655e091b0352e4630d520b54c6ca6d659d1d38fbb4b3bfc9ff3e66db433a2e194ead32bb10ff962c382d800a670e82b7a62835b238e294b22808290ea musl-hvmloader-fix-stdint.patch 8c3b57eab8641bcee3dbdc1937ea7874f77b9722a5a0aa3ddb8dff8cc0ced7e19703ef5d998621b3809bea7c16f3346cfa47610ec9ab014ad0de12651c94e5ff stdint_local.h 853467a2d055c5bfbdc7bdca175a334241be44a7c5ac3c0a84a4bc5463b5c070b66d37e2a557429ef860727a6b7350683af758cc2494d85b6be4d883143a2c0d elf_local.h diff --git a/main/xen/xsa246-4.9.patch b/main/xen/xsa246-4.9.patch deleted file mode 100644 index 6370a10625..0000000000 --- a/main/xen/xsa246-4.9.patch +++ /dev/null @@ -1,74 +0,0 @@ -From: Julien Grall <julien.grall@linaro.org> -Subject: x86/pod: prevent infinite loop when shattering large pages - -When populating pages, the PoD may need to split large ones using -p2m_set_entry and request the caller to retry (see ept_get_entry for -instance). - -p2m_set_entry may fail to shatter if it is not possible to allocate -memory for the new page table. However, the error is not propagated -resulting to the callers to retry infinitely the PoD. - -Prevent the infinite loop by return false when it is not possible to -shatter the large mapping. - -This is XSA-246. - -Signed-off-by: Julien Grall <julien.grall@linaro.org> -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: George Dunlap <george.dunlap@citrix.com> - ---- a/xen/arch/x86/mm/p2m-pod.c -+++ b/xen/arch/x86/mm/p2m-pod.c -@@ -1071,9 +1071,8 @@ p2m_pod_demand_populate(struct p2m_domai - * NOTE: In a fine-grained p2m locking scenario this operation - * may need to promote its locking from gfn->1g superpage - */ -- p2m_set_entry(p2m, gfn_aligned, INVALID_MFN, PAGE_ORDER_2M, -- p2m_populate_on_demand, p2m->default_access); -- return 0; -+ return p2m_set_entry(p2m, gfn_aligned, INVALID_MFN, PAGE_ORDER_2M, -+ p2m_populate_on_demand, p2m->default_access); - } - - /* Only reclaim if we're in actual need of more cache. */ -@@ -1104,8 +1103,12 @@ p2m_pod_demand_populate(struct p2m_domai - - gfn_aligned = (gfn >> order) << order; - -- p2m_set_entry(p2m, gfn_aligned, mfn, order, p2m_ram_rw, -- p2m->default_access); -+ if ( p2m_set_entry(p2m, gfn_aligned, mfn, order, p2m_ram_rw, -+ p2m->default_access) ) -+ { -+ p2m_pod_cache_add(p2m, p, order); -+ goto out_fail; -+ } - - for( i = 0; i < (1UL << order); i++ ) - { -@@ -1150,13 +1153,18 @@ remap_and_retry: - BUG_ON(order != PAGE_ORDER_2M); - pod_unlock(p2m); - -- /* Remap this 2-meg region in singleton chunks */ -- /* NOTE: In a p2m fine-grained lock scenario this might -- * need promoting the gfn lock from gfn->2M superpage */ -+ /* -+ * Remap this 2-meg region in singleton chunks. See the comment on the -+ * 1G page splitting path above for why a single call suffices. -+ * -+ * NOTE: In a p2m fine-grained lock scenario this might -+ * need promoting the gfn lock from gfn->2M superpage. -+ */ - gfn_aligned = (gfn>>order)<<order; -- for(i=0; i<(1<<order); i++) -- p2m_set_entry(p2m, gfn_aligned + i, INVALID_MFN, PAGE_ORDER_4K, -- p2m_populate_on_demand, p2m->default_access); -+ if ( p2m_set_entry(p2m, gfn_aligned, INVALID_MFN, PAGE_ORDER_4K, -+ p2m_populate_on_demand, p2m->default_access) ) -+ return -1; -+ - if ( tb_init_done ) - { - struct { diff --git a/main/xen/xsa247-4.9-1.patch b/main/xen/xsa247-4.9-1.patch deleted file mode 100644 index e86d5616c4..0000000000 --- a/main/xen/xsa247-4.9-1.patch +++ /dev/null @@ -1,176 +0,0 @@ -From ad208b8b7e45fb2b7c572b86c61c26412609e82d Mon Sep 17 00:00:00 2001 -From: George Dunlap <george.dunlap@citrix.com> -Date: Fri, 10 Nov 2017 16:53:54 +0000 -Subject: [PATCH 1/2] p2m: Always check to see if removing a p2m entry actually - worked - -The PoD zero-check functions speculatively remove memory from the p2m, -then check to see if it's completely zeroed, before putting it in the -cache. - -Unfortunately, the p2m_set_entry() calls may fail if the underlying -pagetable structure needs to change and the domain has exhausted its -p2m memory pool: for instance, if we're removing a 2MiB region out of -a 1GiB entry (in the p2m_pod_zero_check_superpage() case), or a 4k -region out of a 2MiB or larger entry (in the p2m_pod_zero_check() -case); and the return value is not checked. - -The underlying mfn will then be added into the PoD cache, and at some -point mapped into another location in the p2m. If the guest -afterwards ballons out this memory, it will be freed to the hypervisor -and potentially reused by another domain, in spite of the fact that -the original domain still has writable mappings to it. - -There are several places where p2m_set_entry() shouldn't be able to -fail, as it is guaranteed to write an entry of the same order that -succeeded before. Add a backstop of crashing the domain just in case, -and an ASSERT_UNREACHABLE() to flag up the broken assumption on debug -builds. - -While we're here, use PAGE_ORDER_2M rather than a magic constant. - -This is part of XSA-247. - -Reported-by: XXX PERSON <XXX EMAIL> -Signed-off-by: George Dunlap <george.dunlap@citrix.com> -Reviewed-by: Jan Beulich <jbeulich@suse.com> ---- -v4: -- Removed some training whitespace -v3: -- Reformat reset clause to be more compact -- Make sure to set map[i] = NULL when unmapping in case we need to bail -v2: -- Crash a domain if a p2m_set_entry we think cannot fail fails anyway. ---- - xen/arch/x86/mm/p2m-pod.c | 77 +++++++++++++++++++++++++++++++++++++---------- - 1 file changed, 61 insertions(+), 16 deletions(-) - -diff --git a/xen/arch/x86/mm/p2m-pod.c b/xen/arch/x86/mm/p2m-pod.c -index 730a48f928..f2ed751892 100644 ---- a/xen/arch/x86/mm/p2m-pod.c -+++ b/xen/arch/x86/mm/p2m-pod.c -@@ -752,8 +752,10 @@ p2m_pod_zero_check_superpage(struct p2m_domain *p2m, unsigned long gfn) - } - - /* Try to remove the page, restoring old mapping if it fails. */ -- p2m_set_entry(p2m, gfn, INVALID_MFN, PAGE_ORDER_2M, -- p2m_populate_on_demand, p2m->default_access); -+ if ( p2m_set_entry(p2m, gfn, INVALID_MFN, PAGE_ORDER_2M, -+ p2m_populate_on_demand, p2m->default_access) ) -+ goto out; -+ - p2m_tlb_flush_sync(p2m); - - /* Make none of the MFNs are used elsewhere... for example, mapped -@@ -810,9 +812,18 @@ p2m_pod_zero_check_superpage(struct p2m_domain *p2m, unsigned long gfn) - ret = SUPERPAGE_PAGES; - - out_reset: -- if ( reset ) -- p2m_set_entry(p2m, gfn, mfn0, 9, type0, p2m->default_access); -- -+ /* -+ * This p2m_set_entry() call shouldn't be able to fail, since the same order -+ * on the same gfn succeeded above. If that turns out to be false, crashing -+ * the domain should be the safest way of making sure we don't leak memory. -+ */ -+ if ( reset && p2m_set_entry(p2m, gfn, mfn0, PAGE_ORDER_2M, -+ type0, p2m->default_access) ) -+ { -+ ASSERT_UNREACHABLE(); -+ domain_crash(d); -+ } -+ - out: - gfn_unlock(p2m, gfn, SUPERPAGE_ORDER); - return ret; -@@ -869,19 +880,30 @@ p2m_pod_zero_check(struct p2m_domain *p2m, unsigned long *gfns, int count) - } - - /* Try to remove the page, restoring old mapping if it fails. */ -- p2m_set_entry(p2m, gfns[i], INVALID_MFN, PAGE_ORDER_4K, -- p2m_populate_on_demand, p2m->default_access); -+ if ( p2m_set_entry(p2m, gfns[i], INVALID_MFN, PAGE_ORDER_4K, -+ p2m_populate_on_demand, p2m->default_access) ) -+ goto skip; - - /* See if the page was successfully unmapped. (Allow one refcount - * for being allocated to a domain.) */ - if ( (mfn_to_page(mfns[i])->count_info & PGC_count_mask) > 1 ) - { -+ /* -+ * If the previous p2m_set_entry call succeeded, this one shouldn't -+ * be able to fail. If it does, crashing the domain should be safe. -+ */ -+ if ( p2m_set_entry(p2m, gfns[i], mfns[i], PAGE_ORDER_4K, -+ types[i], p2m->default_access) ) -+ { -+ ASSERT_UNREACHABLE(); -+ domain_crash(d); -+ goto out_unmap; -+ } -+ -+ skip: - unmap_domain_page(map[i]); - map[i] = NULL; - -- p2m_set_entry(p2m, gfns[i], mfns[i], PAGE_ORDER_4K, -- types[i], p2m->default_access); -- - continue; - } - } -@@ -900,12 +922,25 @@ p2m_pod_zero_check(struct p2m_domain *p2m, unsigned long *gfns, int count) - - unmap_domain_page(map[i]); - -- /* See comment in p2m_pod_zero_check_superpage() re gnttab -- * check timing. */ -- if ( j < PAGE_SIZE/sizeof(*map[i]) ) -+ map[i] = NULL; -+ -+ /* -+ * See comment in p2m_pod_zero_check_superpage() re gnttab -+ * check timing. -+ */ -+ if ( j < (PAGE_SIZE / sizeof(*map[i])) ) - { -- p2m_set_entry(p2m, gfns[i], mfns[i], PAGE_ORDER_4K, -- types[i], p2m->default_access); -+ /* -+ * If the previous p2m_set_entry call succeeded, this one shouldn't -+ * be able to fail. If it does, crashing the domain should be safe. -+ */ -+ if ( p2m_set_entry(p2m, gfns[i], mfns[i], PAGE_ORDER_4K, -+ types[i], p2m->default_access) ) -+ { -+ ASSERT_UNREACHABLE(); -+ domain_crash(d); -+ goto out_unmap; -+ } - } - else - { -@@ -929,7 +964,17 @@ p2m_pod_zero_check(struct p2m_domain *p2m, unsigned long *gfns, int count) - p2m->pod.entry_count++; - } - } -- -+ -+ return; -+ -+out_unmap: -+ /* -+ * Something went wrong, probably crashing the domain. Unmap -+ * everything and return. -+ */ -+ for ( i = 0; i < count; i++ ) -+ if ( map[i] ) -+ unmap_domain_page(map[i]); - } - - #define POD_SWEEP_LIMIT 1024 --- -2.15.0 - diff --git a/main/xen/xsa248.patch b/main/xen/xsa248.patch deleted file mode 100644 index 966c16e043..0000000000 --- a/main/xen/xsa248.patch +++ /dev/null @@ -1,164 +0,0 @@ -From: Jan Beulich <jbeulich@suse.com> -Subject: x86/mm: don't wrongly set page ownership - -PV domains can obtain mappings of any pages owned by the correct domain, -including ones that aren't actually assigned as "normal" RAM, but used -by Xen internally. At the moment such "internal" pages marked as owned -by a guest include pages used to track logdirty bits, as well as p2m -pages and the "unpaged pagetable" for HVM guests. Since the PV memory -management and shadow code conflict in their use of struct page_info -fields, and since shadow code is being used for log-dirty handling for -PV domains, pages coming from the shadow pool must, for PV domains, not -have the domain set as their owner. - -While the change could be done conditionally for just the PV case in -shadow code, do it unconditionally (and for consistency also for HAP), -just to be on the safe side. - -There's one special case though for shadow code: The page table used for -running a HVM guest in unpaged mode is subject to get_page() (in -set_shadow_status()) and hence must have its owner set. - -This is XSA-248. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Tim Deegan <tim@xen.org> -Reviewed-by: George Dunlap <george.dunlap@citrix.com> ---- -v2: Drop PGC_page_table related pieces. - ---- a/xen/arch/x86/mm/hap/hap.c -+++ b/xen/arch/x86/mm/hap/hap.c -@@ -286,8 +286,7 @@ static struct page_info *hap_alloc_p2m_p - { - d->arch.paging.hap.total_pages--; - d->arch.paging.hap.p2m_pages++; -- page_set_owner(pg, d); -- pg->count_info |= 1; -+ ASSERT(!page_get_owner(pg) && !(pg->count_info & PGC_count_mask)); - } - else if ( !d->arch.paging.p2m_alloc_failed ) - { -@@ -302,21 +301,23 @@ static struct page_info *hap_alloc_p2m_p - - static void hap_free_p2m_page(struct domain *d, struct page_info *pg) - { -+ struct domain *owner = page_get_owner(pg); -+ - /* This is called both from the p2m code (which never holds the - * paging lock) and the log-dirty code (which always does). */ - paging_lock_recursive(d); - -- ASSERT(page_get_owner(pg) == d); -- /* Should have just the one ref we gave it in alloc_p2m_page() */ -- if ( (pg->count_info & PGC_count_mask) != 1 ) { -- HAP_ERROR("Odd p2m page %p count c=%#lx t=%"PRtype_info"\n", -- pg, pg->count_info, pg->u.inuse.type_info); -+ /* Should still have no owner and count zero. */ -+ if ( owner || (pg->count_info & PGC_count_mask) ) -+ { -+ HAP_ERROR("d%d: Odd p2m page %"PRI_mfn" d=%d c=%lx t=%"PRtype_info"\n", -+ d->domain_id, mfn_x(page_to_mfn(pg)), -+ owner ? owner->domain_id : DOMID_INVALID, -+ pg->count_info, pg->u.inuse.type_info); - WARN(); -+ pg->count_info &= ~PGC_count_mask; -+ page_set_owner(pg, NULL); - } -- pg->count_info &= ~PGC_count_mask; -- /* Free should not decrement domain's total allocation, since -- * these pages were allocated without an owner. */ -- page_set_owner(pg, NULL); - d->arch.paging.hap.p2m_pages--; - d->arch.paging.hap.total_pages++; - hap_free(d, page_to_mfn(pg)); ---- a/xen/arch/x86/mm/shadow/common.c -+++ b/xen/arch/x86/mm/shadow/common.c -@@ -1503,32 +1503,29 @@ shadow_alloc_p2m_page(struct domain *d) - pg = mfn_to_page(shadow_alloc(d, SH_type_p2m_table, 0)); - d->arch.paging.shadow.p2m_pages++; - d->arch.paging.shadow.total_pages--; -+ ASSERT(!page_get_owner(pg) && !(pg->count_info & PGC_count_mask)); - - paging_unlock(d); - -- /* Unlike shadow pages, mark p2m pages as owned by the domain. -- * Marking the domain as the owner would normally allow the guest to -- * create mappings of these pages, but these p2m pages will never be -- * in the domain's guest-physical address space, and so that is not -- * believed to be a concern. */ -- page_set_owner(pg, d); -- pg->count_info |= 1; - return pg; - } - - static void - shadow_free_p2m_page(struct domain *d, struct page_info *pg) - { -- ASSERT(page_get_owner(pg) == d); -- /* Should have just the one ref we gave it in alloc_p2m_page() */ -- if ( (pg->count_info & PGC_count_mask) != 1 ) -+ struct domain *owner = page_get_owner(pg); -+ -+ /* Should still have no owner and count zero. */ -+ if ( owner || (pg->count_info & PGC_count_mask) ) - { -- SHADOW_ERROR("Odd p2m page count c=%#lx t=%"PRtype_info"\n", -+ SHADOW_ERROR("d%d: Odd p2m page %"PRI_mfn" d=%d c=%lx t=%"PRtype_info"\n", -+ d->domain_id, mfn_x(page_to_mfn(pg)), -+ owner ? owner->domain_id : DOMID_INVALID, - pg->count_info, pg->u.inuse.type_info); -+ pg->count_info &= ~PGC_count_mask; -+ page_set_owner(pg, NULL); - } -- pg->count_info &= ~PGC_count_mask; - pg->u.sh.type = SH_type_p2m_table; /* p2m code reuses type-info */ -- page_set_owner(pg, NULL); - - /* This is called both from the p2m code (which never holds the - * paging lock) and the log-dirty code (which always does). */ -@@ -3132,7 +3129,9 @@ int shadow_enable(struct domain *d, u32 - e = __map_domain_page(pg); - write_32bit_pse_identmap(e); - unmap_domain_page(e); -+ pg->count_info = 1; - pg->u.inuse.type_info = PGT_l2_page_table | 1 | PGT_validated; -+ page_set_owner(pg, d); - } - - paging_lock(d); -@@ -3170,7 +3169,11 @@ int shadow_enable(struct domain *d, u32 - if ( rv != 0 && !pagetable_is_null(p2m_get_pagetable(p2m)) ) - p2m_teardown(p2m); - if ( rv != 0 && pg != NULL ) -+ { -+ pg->count_info &= ~PGC_count_mask; -+ page_set_owner(pg, NULL); - shadow_free_p2m_page(d, pg); -+ } - domain_unpause(d); - return rv; - } -@@ -3279,7 +3282,22 @@ out: - - /* Must be called outside the lock */ - if ( unpaged_pagetable ) -+ { -+ if ( page_get_owner(unpaged_pagetable) == d && -+ (unpaged_pagetable->count_info & PGC_count_mask) == 1 ) -+ { -+ unpaged_pagetable->count_info &= ~PGC_count_mask; -+ page_set_owner(unpaged_pagetable, NULL); -+ } -+ /* Complain here in cases where shadow_free_p2m_page() won't. */ -+ else if ( !page_get_owner(unpaged_pagetable) && -+ !(unpaged_pagetable->count_info & PGC_count_mask) ) -+ SHADOW_ERROR("d%d: Odd unpaged pt %"PRI_mfn" c=%lx t=%"PRtype_info"\n", -+ d->domain_id, mfn_x(page_to_mfn(unpaged_pagetable)), -+ unpaged_pagetable->count_info, -+ unpaged_pagetable->u.inuse.type_info); - shadow_free_p2m_page(d, unpaged_pagetable); -+ } - } - - void shadow_final_teardown(struct domain *d) diff --git a/main/xen/xsa249.patch b/main/xen/xsa249.patch deleted file mode 100644 index ecfa4305e5..0000000000 --- a/main/xen/xsa249.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Jan Beulich <jbeulich@suse.com> -Subject: x86/shadow: fix refcount overflow check - -Commit c385d27079 ("x86 shadow: for multi-page shadows, explicitly track -the first page") reduced the refcount width to 25, without adjusting the -overflow check. Eliminate the disconnect by using a manifest constant. - -Interestingly, up to commit 047782fa01 ("Out-of-sync L1 shadows: OOS -snapshot") the refcount was 27 bits wide, yet the check was already -using 26. - -This is XSA-249. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: George Dunlap <george.dunlap@citrix.com> -Reviewed-by: Tim Deegan <tim@xen.org> ---- -v2: Simplify expression back to the style it was. - ---- a/xen/arch/x86/mm/shadow/private.h -+++ b/xen/arch/x86/mm/shadow/private.h -@@ -529,7 +529,7 @@ static inline int sh_get_ref(struct doma - x = sp->u.sh.count; - nx = x + 1; - -- if ( unlikely(nx >= 1U<<26) ) -+ if ( unlikely(nx >= (1U << PAGE_SH_REFCOUNT_WIDTH)) ) - { - SHADOW_PRINTK("shadow ref overflow, gmfn=%lx smfn=%lx\n", - __backpointer(sp), mfn_x(smfn)); ---- a/xen/include/asm-x86/mm.h -+++ b/xen/include/asm-x86/mm.h -@@ -82,7 +82,8 @@ struct page_info - unsigned long type:5; /* What kind of shadow is this? */ - unsigned long pinned:1; /* Is the shadow pinned? */ - unsigned long head:1; /* Is this the first page of the shadow? */ -- unsigned long count:25; /* Reference count */ -+#define PAGE_SH_REFCOUNT_WIDTH 25 -+ unsigned long count:PAGE_SH_REFCOUNT_WIDTH; /* Reference count */ - } sh; - - /* Page is on a free list: ((count_info & PGC_count_mask) == 0). */ diff --git a/main/xen/xsa250.patch b/main/xen/xsa250.patch deleted file mode 100644 index 26aeb33fed..0000000000 --- a/main/xen/xsa250.patch +++ /dev/null @@ -1,67 +0,0 @@ -From: Jan Beulich <jbeulich@suse.com> -Subject: x86/shadow: fix ref-counting error handling - -The old-Linux handling in shadow_set_l4e() mistakenly ORed together the -results of sh_get_ref() and sh_pin(). As the latter failing is not a -correctness problem, simply ignore its return value. - -In sh_set_toplevel_shadow() a failing sh_get_ref() must not be -accompanied by installing the entry, despite the domain being crashed. - -This is XSA-250. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Tim Deegan <tim@xen.org> - ---- a/xen/arch/x86/mm/shadow/multi.c -+++ b/xen/arch/x86/mm/shadow/multi.c -@@ -923,7 +923,7 @@ static int shadow_set_l4e(struct domain - shadow_l4e_t new_sl4e, - mfn_t sl4mfn) - { -- int flags = 0, ok; -+ int flags = 0; - shadow_l4e_t old_sl4e; - paddr_t paddr; - ASSERT(sl4e != NULL); -@@ -938,15 +938,16 @@ static int shadow_set_l4e(struct domain - { - /* About to install a new reference */ - mfn_t sl3mfn = shadow_l4e_get_mfn(new_sl4e); -- ok = sh_get_ref(d, sl3mfn, paddr); -- /* Are we pinning l3 shadows to handle wierd linux behaviour? */ -- if ( sh_type_is_pinnable(d, SH_type_l3_64_shadow) ) -- ok |= sh_pin(d, sl3mfn); -- if ( !ok ) -+ -+ if ( !sh_get_ref(d, sl3mfn, paddr) ) - { - domain_crash(d); - return SHADOW_SET_ERROR; - } -+ -+ /* Are we pinning l3 shadows to handle weird Linux behaviour? */ -+ if ( sh_type_is_pinnable(d, SH_type_l3_64_shadow) ) -+ sh_pin(d, sl3mfn); - } - - /* Write the new entry */ -@@ -3965,14 +3966,15 @@ sh_set_toplevel_shadow(struct vcpu *v, - - /* Take a ref to this page: it will be released in sh_detach_old_tables() - * or the next call to set_toplevel_shadow() */ -- if ( !sh_get_ref(d, smfn, 0) ) -+ if ( sh_get_ref(d, smfn, 0) ) -+ new_entry = pagetable_from_mfn(smfn); -+ else - { - SHADOW_ERROR("can't install %#lx as toplevel shadow\n", mfn_x(smfn)); - domain_crash(d); -+ new_entry = pagetable_null(); - } - -- new_entry = pagetable_from_mfn(smfn); -- - install_new_entry: - /* Done. Install it */ - SHADOW_PRINTK("%u/%u [%u] gmfn %#"PRI_mfn" smfn %#"PRI_mfn"\n", diff --git a/main/xen/xsa251.patch b/main/xen/xsa251.patch deleted file mode 100644 index 582ef622eb..0000000000 --- a/main/xen/xsa251.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Jan Beulich <jbeulich@suse.com> -Subject: x86/paging: don't unconditionally BUG() on finding SHARED_M2P_ENTRY - -PV guests can fully control the values written into the P2M. - -This is XSA-251. - -Signed-off-by: Jan Beulich <jbeulich@suse.com> -Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> - ---- a/xen/arch/x86/mm/paging.c -+++ b/xen/arch/x86/mm/paging.c -@@ -274,7 +274,7 @@ void paging_mark_pfn_dirty(struct domain - return; - - /* Shared MFNs should NEVER be marked dirty */ -- BUG_ON(SHARED_M2P(pfn_x(pfn))); -+ BUG_ON(paging_mode_translate(d) && SHARED_M2P(pfn_x(pfn))); - - /* - * Values with the MSB set denote MFNs that aren't really part of the diff --git a/main/xen/xsa253-4.10.patch b/main/xen/xsa253-4.10.patch new file mode 100644 index 0000000000..19e4269358 --- /dev/null +++ b/main/xen/xsa253-4.10.patch @@ -0,0 +1,26 @@ +From: Andrew Cooper <andrew.cooper3@citrix.com> +Subject: x86/msr: Free msr_vcpu_policy during vcpu destruction + +c/s 4187f79dc7 "x86/msr: introduce struct msr_vcpu_policy" introduced a +per-vcpu memory allocation, but failed to free it in the clean vcpu +destruction case. + +This is XSA-253 + +Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> +Reviewed-by: Jan Beulich <jbeulich@suse.com> + +diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c +index b17468c..0ae715d 100644 +--- a/xen/arch/x86/domain.c ++++ b/xen/arch/x86/domain.c +@@ -382,6 +382,9 @@ void vcpu_destroy(struct vcpu *v) + + vcpu_destroy_fpu(v); + ++ xfree(v->arch.msr); ++ v->arch.msr = NULL; ++ + if ( !is_idle_domain(v->domain) ) + vpmu_destroy(v); + diff --git a/main/xen/0003-x86-Meltdown-band-aid-against-malicious-64-bit-PV-gu.patch b/main/xen/xsa254-4.10.patch index 296bbe8484..deb04bf549 100644 --- a/main/xen/0003-x86-Meltdown-band-aid-against-malicious-64-bit-PV-gu.patch +++ b/main/xen/xsa254-4.10.patch @@ -1,7 +1,459 @@ -From 92884bbf6c424c402ae76e6da06e62cd33714cb3 Mon Sep 17 00:00:00 2001 +From 910dd005da20f27f3415b7eccdf436874989506b Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Wed, 17 Jan 2018 16:54:44 +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/pv/domain.c | 1 - + xen/arch/x86/pv/emul-priv-op.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 | 105 +++------------------------------ + 10 files changed, 26 insertions(+), 125 deletions(-) + +diff --git a/tools/tests/x86_emulator/x86-emulate.c b/tools/tests/x86_emulator/x86-emulate.c +index 975ddc7..9056610 100644 +--- a/tools/tests/x86_emulator/x86-emulate.c ++++ b/tools/tests/x86_emulator/x86-emulate.c +@@ -3,7 +3,6 @@ + #include <sys/mman.h> + + #define cpu_has_amd_erratum(nr) 0 +-#define mark_regs_dirty(r) ((void)(r)) + #define cpu_has_mpx false + #define read_bndcfgu() 0 + #define xstate_set_init(what) +diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c +index 2234128..74e9e66 100644 +--- a/xen/arch/x86/pv/domain.c ++++ b/xen/arch/x86/pv/domain.c +@@ -20,7 +20,6 @@ + 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/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c +index 2f92645..5f23c2c 100644 +--- a/xen/arch/x86/pv/emul-priv-op.c ++++ b/xen/arch/x86/pv/emul-priv-op.c +@@ -337,7 +337,6 @@ static int read_io(unsigned int port, unsigned int bytes, + io_emul_stub_t *io_emul = + io_emul_stub_setup(poc, ctxt->opcode, port, bytes); + +- mark_regs_dirty(ctxt->regs); + io_emul(ctxt->regs); + return X86EMUL_DONE; + } +@@ -436,7 +435,6 @@ static int write_io(unsigned int port, unsigned int bytes, + io_emul_stub_t *io_emul = + io_emul_stub_setup(poc, ctxt->opcode, port, bytes); + +- mark_regs_dirty(ctxt->regs); + io_emul(ctxt->regs); + if ( (bytes == 1) && pv_post_outb_hook ) + pv_post_outb_hook(port, val); +diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S +index ba6e941..3fea54e 100644 +--- a/xen/arch/x86/x86_64/compat/entry.S ++++ b/xen/arch/x86/x86_64/compat/entry.S +@@ -16,7 +16,8 @@ + ENTRY(entry_int82) + ASM_CLAC + pushq $0 +- SAVE_VOLATILE type=HYPERCALL_VECTOR compat=1 ++ movl $HYPERCALL_VECTOR, 4(%rsp) ++ SAVE_ALL compat=1 /* DPL1 gate, restricted to 32bit PV guests only. */ + CR4_PV32_RESTORE + + GET_CURRENT(bx) +@@ -60,7 +61,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 + +@@ -197,7 +197,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 6066ed8..1dd9ccf 100644 +--- a/xen/arch/x86/x86_64/entry.S ++++ b/xen/arch/x86/x86_64/entry.S +@@ -98,7 +98,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 +@@ -140,7 +141,6 @@ test_guest_events: + /* %rbx: struct vcpu */ + process_softirqs: + sti +- SAVE_PRESERVED + call do_softirq + jmp test_all_events + +@@ -190,7 +190,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 +@@ -207,7 +208,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 +@@ -225,7 +225,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) +@@ -253,7 +254,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 2a326be..3652f5f 100644 +--- a/xen/arch/x86/x86_64/traps.c ++++ b/xen/arch/x86/x86_64/traps.c +@@ -80,15 +80,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 cc334ca..c7ba221 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/xstate.h> + #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 54a2756..820495f 100644 +--- a/xen/arch/x86/x86_emulate/x86_emulate.c ++++ b/xen/arch/x86/x86_emulate/x86_emulate.c +@@ -1956,10 +1956,10 @@ decode_register( + case 9: p = ®s->r9; break; + case 10: p = ®s->r10; break; + case 11: p = ®s->r11; break; +- case 12: mark_regs_dirty(regs); p = ®s->r12; break; +- case 13: mark_regs_dirty(regs); p = ®s->r13; break; +- case 14: mark_regs_dirty(regs); p = ®s->r14; break; +- case 15: mark_regs_dirty(regs); p = ®s->r15; break; ++ case 12: p = ®s->r12; break; ++ case 13: p = ®s->r13; break; ++ case 14: p = ®s->r14; break; ++ case 15: p = ®s->r15; break; + #endif + default: BUG(); p = NULL; break; + } +diff --git a/xen/common/wait.c b/xen/common/wait.c +index 9490a17..c5fc094 100644 +--- a/xen/common/wait.c ++++ b/xen/common/wait.c +@@ -127,7 +127,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 388fc93..98192eb 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) \ +@@ -330,7 +259,6 @@ static always_inline void stac(void) + */ + .macro RESTORE_ALL adj=0 compat=0 + .if !\compat +- testl $TRAP_regs_dirty,UREGS_entry_vector(%rsp) + movq UREGS_r11(%rsp),%r11 + movq UREGS_r10(%rsp),%r10 + movq UREGS_r9(%rsp),%r9 +@@ -347,33 +275,16 @@ static always_inline void stac(void) + LOAD_ONE_REG(si, \compat) + LOAD_ONE_REG(di, \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 + .else + xor %r15, %r15 + xor %r14, %r14 + xor %r13, %r13 + xor %r12, %r12 + .endif +-987: + LOAD_ONE_REG(bp, \compat) + LOAD_ONE_REG(bx, \compat) + subq $-(UREGS_error_code-UREGS_r15+\adj), %rsp +-- +2.1.4 + +From 57dc197cf0d36c56ba1d9d32c6a1454bb52605bb Mon Sep 17 00:00:00 2001 +From: Andrew Cooper <andrew.cooper3@citrix.com> +Date: Wed, 17 Jan 2018 16:56:03 +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/pv/mm.h | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +diff --git a/xen/arch/x86/pv/mm.h b/xen/arch/x86/pv/mm.h +index 7502d53..976209b 100644 +--- a/xen/arch/x86/pv/mm.h ++++ b/xen/arch/x86/pv/mm.h +@@ -144,9 +144,21 @@ static inline l3_pgentry_t unadjust_guest_l3e(l3_pgentry_t l3e, + static inline l4_pgentry_t adjust_guest_l4e(l4_pgentry_t l4e, + const struct domain *d) + { +- if ( likely(l4e_get_flags(l4e) & _PAGE_PRESENT) && +- likely(!is_pv_32bit_domain(d)) ) +- l4e_add_flags(l4e, _PAGE_USER); ++ /* ++ * 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. ++ */ ++ if ( likely(l4e_get_flags(l4e) & _PAGE_PRESENT) ) ++ l4e_add_flags(l4e, (_PAGE_ACCESSED | ++ (is_pv_32bit_domain(d) ? 0 : _PAGE_USER))); + + return l4e; + } +-- +2.1.4 + +From 234f481337ea1a93db968d614649a6bdfdc8418a Mon Sep 17 00:00:00 2001 From: Jan Beulich <jbeulich@suse.com> -Date: Wed, 17 Jan 2018 17:07:33 +0100 -Subject: [PATCH 3/4] x86: Meltdown band-aid against malicious 64-bit PV guests +Date: Wed, 17 Jan 2018 16:56:57 +0100 +Subject: [PATCH] x86: Meltdown band-aid against malicious 64-bit PV guests This is a very simplistic change limiting the amount of memory a running 64-bit PV guest has mapped (and hence available for attacking): Only the @@ -29,7 +481,6 @@ Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> master commit: 5784de3e2067ed73efc2fe42e62831e8ae7f46c4 master date: 2018-01-16 17:49:03 +0100 -(cherry picked from commit 1e0974638d65d9b8acf9ac7511d747188f38bcc3) --- xen/arch/x86/domain.c | 5 + xen/arch/x86/mm.c | 21 ++++ @@ -44,12 +495,12 @@ master date: 2018-01-16 17:49:03 +0100 10 files changed, 428 insertions(+), 6 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c -index 07b50315b9..c0f0fc7a32 100644 +index b44c95b..f4a3d74 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c -@@ -1933,6 +1933,9 @@ static void paravirt_ctxt_switch_to(struct vcpu *v) - - switch_kernel_stack(v); +@@ -1507,6 +1507,9 @@ void paravirt_ctxt_switch_to(struct vcpu *v) + { + unsigned long cr4; + this_cpu(root_pgt)[root_table_offset(PERDOMAIN_VIRT_START)] = + l4e_from_page(v->domain->arch.perdomain_l3_pg, __PAGE_HYPERVISOR_RW); @@ -57,7 +508,7 @@ index 07b50315b9..c0f0fc7a32 100644 cr4 = pv_guest_cr4_to_real_cr4(v); if ( unlikely(cr4 != read_cr4()) ) write_cr4(cr4); -@@ -2102,6 +2105,8 @@ void context_switch(struct vcpu *prev, struct vcpu *next) +@@ -1676,6 +1679,8 @@ void context_switch(struct vcpu *prev, struct vcpu *next) ASSERT(local_irq_is_enabled()); @@ -67,18 +518,18 @@ index 07b50315b9..c0f0fc7a32 100644 /* Allow at most one CPU at a time to be dirty. */ ASSERT(cpumask_weight(&dirty_mask) <= 1); diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c -index 981458907f..78f4cb37f5 100644 +index a7a76a7..6c7d120 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c -@@ -3906,6 +3906,7 @@ long do_mmu_update( +@@ -3509,6 +3509,7 @@ long do_mmu_update( struct vcpu *curr = current, *v = curr; struct domain *d = v->domain, *pt_owner = d, *pg_owner; - struct domain_mmap_cache mapcache; + mfn_t map_mfn = INVALID_MFN; + bool sync_guest = false; uint32_t xsm_needed = 0; uint32_t xsm_checked = 0; int rc = put_old_guest_table(curr); -@@ -4054,6 +4055,8 @@ long do_mmu_update( +@@ -3663,6 +3664,8 @@ long do_mmu_update( case PGT_l4_page_table: rc = mod_l4_entry(va, l4e_from_intpte(req.val), mfn, cmd == MMU_PT_UPDATE_PRESERVE_AD, v); @@ -87,9 +538,9 @@ index 981458907f..78f4cb37f5 100644 break; case PGT_writable_page: perfc_incr(writable_mmu_updates); -@@ -4156,6 +4159,24 @@ long do_mmu_update( - - domain_mmap_cache_destroy(&mapcache); +@@ -3765,6 +3768,24 @@ long do_mmu_update( + if ( va ) + unmap_domain_page(va); + if ( sync_guest ) + { @@ -113,10 +564,10 @@ index 981458907f..78f4cb37f5 100644 out: diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c -index 26b5301dcc..965a49f923 100644 +index 1609b62..b1fbb57 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c -@@ -321,6 +321,9 @@ void start_secondary(void *unused) +@@ -327,6 +327,9 @@ void start_secondary(void *unused) */ spin_debug_disable(); @@ -354,7 +805,7 @@ index 26b5301dcc..965a49f923 100644 set_nr_sockets(); socket_cpumask = xzalloc_array(cpumask_t *, nr_sockets); -@@ -865,6 +1061,8 @@ void __init smp_prepare_boot_cpu(void) +@@ -864,6 +1060,8 @@ void __init smp_prepare_boot_cpu(void) #if NR_CPUS > 2 * BITS_PER_LONG per_cpu(scratch_cpumask, cpu) = &scratch_cpu0mask; #endif @@ -364,7 +815,7 @@ index 26b5301dcc..965a49f923 100644 static void diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c -index e136af6b99..b1a4310974 100644 +index e136af6..b1a4310 100644 --- a/xen/arch/x86/x86_64/asm-offsets.c +++ b/xen/arch/x86/x86_64/asm-offsets.c @@ -137,6 +137,8 @@ void __dummy__(void) @@ -377,10 +828,10 @@ index e136af6b99..b1a4310974 100644 BLANK(); diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S -index 37864a67f3..86ab78063a 100644 +index 3fea54e..e668f00 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S -@@ -197,6 +197,17 @@ ENTRY(cstar_enter) +@@ -199,6 +199,17 @@ ENTRY(cstar_enter) pushq $0 movl $TRAP_syscall, 4(%rsp) SAVE_ALL @@ -399,10 +850,10 @@ index 37864a67f3..86ab78063a 100644 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 668bf8ac28..16cf095ee1 100644 +index 1dd9ccf..fc38874 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S -@@ -35,6 +35,32 @@ ENTRY(switch_to_kernel) +@@ -37,6 +37,32 @@ ENTRY(switch_to_kernel) /* %rbx: struct vcpu, interrupts disabled */ restore_all_guest: ASSERT_INTERRUPTS_DISABLED @@ -435,7 +886,7 @@ index 668bf8ac28..16cf095ee1 100644 RESTORE_ALL testw $TRAP_syscall,4(%rsp) jz iret_exit_to_guest -@@ -69,6 +95,22 @@ iret_exit_to_guest: +@@ -71,6 +97,22 @@ iret_exit_to_guest: ALIGN /* No special register assumptions. */ restore_all_xen: @@ -458,7 +909,7 @@ index 668bf8ac28..16cf095ee1 100644 RESTORE_ALL adj=8 iretq -@@ -98,7 +140,18 @@ ENTRY(lstar_enter) +@@ -100,7 +142,18 @@ ENTRY(lstar_enter) pushq $0 movl $TRAP_syscall, 4(%rsp) SAVE_ALL @@ -478,7 +929,7 @@ index 668bf8ac28..16cf095ee1 100644 testb $TF_kernel_mode,VCPU_thread_flags(%rbx) jz switch_to_kernel -@@ -190,7 +243,18 @@ GLOBAL(sysenter_eflags_saved) +@@ -192,7 +245,18 @@ GLOBAL(sysenter_eflags_saved) pushq $0 movl $TRAP_syscall, 4(%rsp) SAVE_ALL @@ -498,7 +949,7 @@ index 668bf8ac28..16cf095ee1 100644 cmpb $0,VCPU_sysenter_disables_events(%rbx) movq VCPU_sysenter_addr(%rbx),%rax setne %cl -@@ -226,13 +290,23 @@ ENTRY(int80_direct_trap) +@@ -228,13 +292,23 @@ ENTRY(int80_direct_trap) movl $0x80, 4(%rsp) SAVE_ALL @@ -523,7 +974,7 @@ index 668bf8ac28..16cf095ee1 100644 /* Check that the callback is non-null. */ leaq VCPU_int80_bounce(%rbx),%rdx -@@ -389,9 +463,27 @@ ENTRY(dom_crash_sync_extable) +@@ -391,9 +465,27 @@ ENTRY(dom_crash_sync_extable) ENTRY(common_interrupt) SAVE_ALL CLAC @@ -551,7 +1002,7 @@ index 668bf8ac28..16cf095ee1 100644 jmp ret_from_intr /* No special register assumptions. */ -@@ -409,6 +501,23 @@ ENTRY(page_fault) +@@ -411,6 +503,23 @@ ENTRY(page_fault) /* No special register assumptions. */ GLOBAL(handle_exception) SAVE_ALL CLAC @@ -575,7 +1026,7 @@ index 668bf8ac28..16cf095ee1 100644 handle_exception_saved: GET_CURRENT(bx) testb $X86_EFLAGS_IF>>8,UREGS_eflags+1(%rsp) -@@ -473,6 +582,7 @@ handle_exception_saved: +@@ -475,6 +584,7 @@ handle_exception_saved: leaq exception_table(%rip),%rdx PERFC_INCR(exceptions, %rax, %rbx) callq *(%rdx,%rax,8) @@ -583,7 +1034,7 @@ index 668bf8ac28..16cf095ee1 100644 testb $3,UREGS_cs(%rsp) jz restore_all_xen leaq VCPU_trap_bounce(%rbx),%rdx -@@ -505,6 +615,7 @@ exception_with_ints_disabled: +@@ -507,6 +617,7 @@ exception_with_ints_disabled: rep; movsq # make room for ec/ev 1: movq UREGS_error_code(%rsp),%rax # ec/ev movq %rax,UREGS_kernel_sizeof(%rsp) @@ -591,7 +1042,7 @@ index 668bf8ac28..16cf095ee1 100644 jmp restore_all_xen # return to fixup code /* No special register assumptions. */ -@@ -583,6 +694,17 @@ ENTRY(double_fault) +@@ -585,6 +696,17 @@ ENTRY(double_fault) movl $TRAP_double_fault,4(%rsp) /* Set AC to reduce chance of further SMAP faults */ SAVE_ALL STAC @@ -609,7 +1060,7 @@ index 668bf8ac28..16cf095ee1 100644 movq %rsp,%rdi call do_double_fault BUG /* do_double_fault() shouldn't return. */ -@@ -601,10 +723,28 @@ ENTRY(nmi) +@@ -603,10 +725,28 @@ ENTRY(nmi) movl $TRAP_nmi,4(%rsp) handle_ist_exception: SAVE_ALL CLAC @@ -639,7 +1090,7 @@ index 668bf8ac28..16cf095ee1 100644 GET_CPUINFO_FIELD(guest_cpu_user_regs,di) movq %rsp,%rsi movl $UREGS_kernel_sizeof/8,%ecx -@@ -614,6 +754,7 @@ handle_ist_exception: +@@ -616,6 +756,7 @@ handle_ist_exception: movzbl UREGS_entry_vector(%rsp),%eax leaq exception_table(%rip),%rdx callq *(%rdx,%rax,8) @@ -648,7 +1099,7 @@ index 668bf8ac28..16cf095ee1 100644 jne ret_from_intr diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h -index 98192eb4e6..fb0fee9286 100644 +index 98192eb..fb0fee9 100644 --- a/xen/include/asm-x86/asm_defns.h +++ b/xen/include/asm-x86/asm_defns.h @@ -93,9 +93,30 @@ void ret_from_intr(void); @@ -699,7 +1150,7 @@ index 98192eb4e6..fb0fee9286 100644 667: ASM_NOP5; \ .pushsection .altinstr_replacement, "ax"; \ diff --git a/xen/include/asm-x86/current.h b/xen/include/asm-x86/current.h -index 89849929eb..b929c48c85 100644 +index 8984992..b929c48 100644 --- a/xen/include/asm-x86/current.h +++ b/xen/include/asm-x86/current.h @@ -41,6 +41,18 @@ struct cpu_info { @@ -722,10 +1173,10 @@ index 89849929eb..b929c48c85 100644 }; diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h -index 00cc23ce40..0291e82de3 100644 +index 41a8d8c..2962e83 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h -@@ -466,6 +466,7 @@ extern idt_entry_t idt_table[]; +@@ -462,6 +462,7 @@ extern idt_entry_t idt_table[]; extern idt_entry_t *idt_tables[]; DECLARE_PER_CPU(struct tss_struct, init_tss); @@ -734,10 +1185,10 @@ index 00cc23ce40..0291e82de3 100644 extern void init_int80_direct_trap(struct vcpu *v); diff --git a/xen/include/asm-x86/x86_64/page.h b/xen/include/asm-x86/x86_64/page.h -index 1a6cae6283..749554fbbb 100644 +index 6fb7cd5..05a0334 100644 --- a/xen/include/asm-x86/x86_64/page.h +++ b/xen/include/asm-x86/x86_64/page.h -@@ -25,8 +25,8 @@ +@@ -24,8 +24,8 @@ /* These are architectural limits. Current CPUs support only 40-bit phys. */ #define PADDR_BITS 52 #define VADDR_BITS 48 @@ -746,9 +1197,9 @@ index 1a6cae6283..749554fbbb 100644 +#define PADDR_MASK ((_AC(1,UL) << PADDR_BITS) - 1) +#define VADDR_MASK ((_AC(1,UL) << VADDR_BITS) - 1) - #define is_canonical_address(x) (((long)(x) >> 47) == ((long)(x) >> 63)) - -@@ -116,6 +116,7 @@ typedef l4_pgentry_t root_pgentry_t; + #define VADDR_TOP_BIT (1UL << (VADDR_BITS - 1)) + #define CANONICAL_MASK (~0UL & ~VADDR_MASK) +@@ -107,6 +107,7 @@ typedef l4_pgentry_t root_pgentry_t; : (((_s) < ROOT_PAGETABLE_FIRST_XEN_SLOT) || \ ((_s) > ROOT_PAGETABLE_LAST_XEN_SLOT))) @@ -757,5 +1208,166 @@ index 1a6cae6283..749554fbbb 100644 #define root_get_flags l4e_get_flags #define root_get_intpte l4e_get_intpte -- -2.15.0 +2.1.4 + +From 7cccd6f748ec724cf9408cec6b3ec8e54a8a2c1f Mon Sep 17 00:00:00 2001 +From: Jan Beulich <jbeulich@suse.com> +Date: Wed, 17 Jan 2018 16:57:33 +0100 +Subject: [PATCH] x86: allow Meltdown band-aid to be disabled + +First of all we don't need it on AMD systems. Additionally allow its use +to be controlled by command line option. For best backportability, this +intentionally doesn't use alternative instruction patching to achieve +the intended effect - while we likely want it, this will be later +follow-up. + +Signed-off-by: Jan Beulich <jbeulich@suse.com> +Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> +master commit: e871e80c38547d9faefc6604532ba3e985e65873 +master date: 2018-01-16 17:50:59 +0100 +--- + docs/misc/xen-command-line.markdown | 12 ++++++++++++ + xen/arch/x86/domain.c | 7 +++++-- + xen/arch/x86/mm.c | 2 +- + xen/arch/x86/smpboot.c | 17 ++++++++++++++--- + xen/arch/x86/x86_64/entry.S | 2 ++ + 5 files changed, 34 insertions(+), 6 deletions(-) + +diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown +index 781110d..49539b4 100644 +--- a/docs/misc/xen-command-line.markdown ++++ b/docs/misc/xen-command-line.markdown +@@ -1849,6 +1849,18 @@ In the case that x2apic is in use, this option switches between physical and + clustered mode. The default, given no hint from the **FADT**, is cluster + mode. + ++### xpti ++> `= <boolean>` ++ ++> Default: `false` on AMD hardware ++> Default: `true` everywhere else ++ ++Override default selection of whether to isolate 64-bit PV guest page ++tables. ++ ++** WARNING: Not yet a complete isolation implementation, but better than ++nothing. ** ++ + ### xsave + > `= <boolean>` + +diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c +index f4a3d74..b357b60 100644 +--- a/xen/arch/x86/domain.c ++++ b/xen/arch/x86/domain.c +@@ -1505,10 +1505,13 @@ void paravirt_ctxt_switch_from(struct vcpu *v) + + void paravirt_ctxt_switch_to(struct vcpu *v) + { ++ root_pgentry_t *root_pgt = this_cpu(root_pgt); + unsigned long cr4; + +- this_cpu(root_pgt)[root_table_offset(PERDOMAIN_VIRT_START)] = +- l4e_from_page(v->domain->arch.perdomain_l3_pg, __PAGE_HYPERVISOR_RW); ++ if ( root_pgt ) ++ root_pgt[root_table_offset(PERDOMAIN_VIRT_START)] = ++ l4e_from_page(v->domain->arch.perdomain_l3_pg, ++ __PAGE_HYPERVISOR_RW); + + cr4 = pv_guest_cr4_to_real_cr4(v); + if ( unlikely(cr4 != read_cr4()) ) +diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c +index 6c7d120..53295f8 100644 +--- a/xen/arch/x86/mm.c ++++ b/xen/arch/x86/mm.c +@@ -3665,7 +3665,7 @@ long do_mmu_update( + rc = mod_l4_entry(va, l4e_from_intpte(req.val), mfn, + cmd == MMU_PT_UPDATE_PRESERVE_AD, v); + if ( !rc ) +- sync_guest = true; ++ sync_guest = this_cpu(root_pgt); + break; + case PGT_writable_page: + perfc_incr(writable_mmu_updates); +diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c +index b1fbb57..edf607f 100644 +--- a/xen/arch/x86/smpboot.c ++++ b/xen/arch/x86/smpboot.c +@@ -328,7 +328,7 @@ void start_secondary(void *unused) + spin_debug_disable(); + + get_cpu_info()->xen_cr3 = 0; +- get_cpu_info()->pv_cr3 = __pa(this_cpu(root_pgt)); ++ get_cpu_info()->pv_cr3 = this_cpu(root_pgt) ? __pa(this_cpu(root_pgt)) : 0; + + load_system_tables(); + +@@ -736,14 +736,20 @@ static int clone_mapping(const void *ptr, root_pgentry_t *rpt) + return 0; + } + ++static __read_mostly int8_t opt_xpti = -1; ++boolean_param("xpti", opt_xpti); + DEFINE_PER_CPU(root_pgentry_t *, root_pgt); + + static int setup_cpu_root_pgt(unsigned int cpu) + { +- root_pgentry_t *rpt = alloc_xen_pagetable(); ++ root_pgentry_t *rpt; + unsigned int off; + int rc; + ++ if ( !opt_xpti ) ++ return 0; ++ ++ rpt = alloc_xen_pagetable(); + if ( !rpt ) + return -ENOMEM; + +@@ -987,10 +993,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) + + stack_base[0] = stack_start; + ++ if ( opt_xpti < 0 ) ++ opt_xpti = boot_cpu_data.x86_vendor != X86_VENDOR_AMD; ++ + rc = setup_cpu_root_pgt(0); + if ( rc ) + panic("Error %d setting up PV root page table\n", rc); +- get_cpu_info()->pv_cr3 = __pa(per_cpu(root_pgt, 0)); ++ if ( per_cpu(root_pgt, 0) ) ++ get_cpu_info()->pv_cr3 = __pa(per_cpu(root_pgt, 0)); + + set_nr_sockets(); + +@@ -1062,6 +1072,7 @@ void __init smp_prepare_boot_cpu(void) + #endif + + get_cpu_info()->xen_cr3 = 0; ++ get_cpu_info()->pv_cr3 = 0; + } + + static void +diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S +index fc38874..a8825c8 100644 +--- a/xen/arch/x86/x86_64/entry.S ++++ b/xen/arch/x86/x86_64/entry.S +@@ -46,6 +46,7 @@ restore_all_guest: + movabs $DIRECTMAP_VIRT_START, %rcx + mov %rdi, %rax + and %rsi, %rdi ++ jz .Lrag_keep_cr3 + and %r9, %rsi + add %rcx, %rdi + add %rcx, %rsi +@@ -62,6 +63,7 @@ restore_all_guest: + rep movsq + mov %r9, STACK_CPUINFO_FIELD(xen_cr3)(%rdx) + write_cr3 rax, rdi, rsi ++.Lrag_keep_cr3: + + RESTORE_ALL + testw $TRAP_syscall,4(%rsp) +-- +2.1.4 |