[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] x86/traps: Rework #PF[Rsvd] bit handling
On 18/05/2020 16:38, Andrew Cooper wrote: > The reserved_bit_page_fault() paths effectively turn reserved bit faults into > a warning, but in the light of L1TF, the real impact is far more serious. > > Xen does not have any reserved bits set in its pagetables, nor do we permit PV > guests to write any. An HVM shadow guest may have reserved bits via the MMIO > fastpath, but those faults are handled in the VMExit #PF intercept, rather > than Xen's #PF handler. > > There is no need to disable interrupts (in spurious_page_fault()) for > __page_fault_type() to look at the rsvd bit, nor should extable fixup be > tolerated. > > Make #PF[Rsvd] a hard error, irrespective of mode. Any new panic() caused by > this constitutes an L1TF gadget needing fixing. > > Additionally, drop the comment for do_page_fault(). It is inaccurate (bit 0 > being set isn't always a protection violation) and stale (missing bits > 5,6,15,31). > > Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> > --- > CC: Jan Beulich <JBeulich@xxxxxxxx> > CC: Wei Liu <wl@xxxxxxx> > CC: Roger Pau Monné <roger.pau@xxxxxxxxxx> > --- > xen/arch/x86/traps.c | 39 +++++++++++++-------------------------- > 1 file changed, 13 insertions(+), 26 deletions(-) > > diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c > index 73c6218660..4f8e3c7a32 100644 > --- a/xen/arch/x86/traps.c > +++ b/xen/arch/x86/traps.c > @@ -1137,15 +1137,6 @@ void do_int3(struct cpu_user_regs *regs) > pv_inject_hw_exception(TRAP_int3, X86_EVENT_NO_EC); > } > > -static void reserved_bit_page_fault(unsigned long addr, > - struct cpu_user_regs *regs) > -{ > - printk("%pv: reserved bit in page table (ec=%04X)\n", > - current, regs->error_code); > - show_page_walk(addr); > - show_execution_state(regs); > -} > - > #ifdef CONFIG_PV > static int handle_ldt_mapping_fault(unsigned int offset, > struct cpu_user_regs *regs) > @@ -1248,10 +1239,6 @@ static enum pf_type __page_fault_type(unsigned long > addr, > if ( in_irq() ) > return real_fault; > > - /* Reserved bit violations are never spurious faults. */ > - if ( error_code & PFEC_reserved_bit ) > - return real_fault; > - > required_flags = _PAGE_PRESENT; > if ( error_code & PFEC_write_access ) > required_flags |= _PAGE_RW; > @@ -1413,14 +1400,6 @@ static int fixup_page_fault(unsigned long addr, struct > cpu_user_regs *regs) > return 0; > } > > -/* > - * #PF error code: > - * Bit 0: Protection violation (=1) ; Page not present (=0) > - * Bit 1: Write access > - * Bit 2: User mode (=1) ; Supervisor mode (=0) > - * Bit 3: Reserved bit violation > - * Bit 4: Instruction fetch > - */ > void do_page_fault(struct cpu_user_regs *regs) > { > unsigned long addr, fixup; > @@ -1439,6 +1418,18 @@ void do_page_fault(struct cpu_user_regs *regs) > if ( unlikely(fixup_page_fault(addr, regs) != 0) ) > return; > > + /* > + * Xen have reserved bits in its pagetables, nor do we permit PV guests > to This should read "Xen doesn't have" ~Andrew > + * write any. Such entries would be vulnerable to the L1TF sidechannel. > + * > + * The only logic which intentionally sets reserved bits is the shadow > + * MMIO fastpath (SH_L1E_MMIO_*), which is careful not to be > + * L1TF-vulnerable, and handled via the VMExit #PF intercept path, rather > + * than here. > + */ > + if ( error_code & PFEC_reserved_bit ) > + goto fatal; > + > if ( unlikely(!guest_mode(regs)) ) > { > enum pf_type pf_type = spurious_page_fault(addr, regs); > @@ -1457,13 +1448,12 @@ void do_page_fault(struct cpu_user_regs *regs) > if ( likely((fixup = search_exception_table(regs)) != 0) ) > { > perfc_incr(copy_user_faults); > - if ( unlikely(regs->error_code & PFEC_reserved_bit) ) > - reserved_bit_page_fault(addr, regs); > this_cpu(last_extable_addr) = regs->rip; > regs->rip = fixup; > return; > } > > + fatal: > if ( debugger_trap_fatal(TRAP_page_fault, regs) ) > return; > > @@ -1475,9 +1465,6 @@ void do_page_fault(struct cpu_user_regs *regs) > error_code, _p(addr)); > } > > - if ( unlikely(regs->error_code & PFEC_reserved_bit) ) > - reserved_bit_page_fault(addr, regs); > - > pv_inject_page_fault(regs->error_code, addr); > } >
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |