|
|
4b77cf7 |
From: Jan Beulich <jbeulich@suse.com>
|
|
|
4b77cf7 |
Subject: x86/HVM: don't load LDTR with VM86 mode attrs during task switch
|
|
|
4b77cf7 |
|
|
|
4b77cf7 |
Just like TR, LDTR is purely a protected mode facility and hence needs
|
|
|
4b77cf7 |
to be loaded accordingly. Also move its loading to where it
|
|
|
4b77cf7 |
architecurally belongs.
|
|
|
4b77cf7 |
|
|
|
4b77cf7 |
This is XSA-192.
|
|
|
4b77cf7 |
|
|
|
4b77cf7 |
Signed-off-by: Jan Beulich <jbeulich@suse.com>
|
|
|
4b77cf7 |
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
|
4b77cf7 |
Tested-by: Andrew Cooper <andrew.cooper3@citrix.com>
|
|
|
4b77cf7 |
|
|
|
4b77cf7 |
--- a/xen/arch/x86/hvm/hvm.c
|
|
|
4b77cf7 |
+++ b/xen/arch/x86/hvm/hvm.c
|
|
|
4b77cf7 |
@@ -3577,16 +3577,15 @@ static void hvm_unmap_entry(void *p)
|
|
|
4b77cf7 |
}
|
|
|
4b77cf7 |
|
|
|
4b77cf7 |
static int hvm_load_segment_selector(
|
|
|
4b77cf7 |
- enum x86_segment seg, uint16_t sel)
|
|
|
4b77cf7 |
+ enum x86_segment seg, uint16_t sel, unsigned int eflags)
|
|
|
4b77cf7 |
{
|
|
|
4b77cf7 |
struct segment_register desctab, cs, segr;
|
|
|
4b77cf7 |
struct desc_struct *pdesc, desc;
|
|
|
4b77cf7 |
u8 dpl, rpl, cpl;
|
|
|
4b77cf7 |
int fault_type = TRAP_invalid_tss;
|
|
|
4b77cf7 |
- struct cpu_user_regs *regs = guest_cpu_user_regs();
|
|
|
4b77cf7 |
struct vcpu *v = current;
|
|
|
4b77cf7 |
|
|
|
4b77cf7 |
- if ( regs->eflags & X86_EFLAGS_VM )
|
|
|
4b77cf7 |
+ if ( eflags & X86_EFLAGS_VM )
|
|
|
4b77cf7 |
{
|
|
|
4b77cf7 |
segr.sel = sel;
|
|
|
4b77cf7 |
segr.base = (uint32_t)sel << 4;
|
|
|
4b77cf7 |
@@ -3829,6 +3828,8 @@ void hvm_task_switch(
|
|
|
4b77cf7 |
if ( rc != HVMCOPY_okay )
|
|
|
4b77cf7 |
goto out;
|
|
|
4b77cf7 |
|
|
|
4b77cf7 |
+ if ( hvm_load_segment_selector(x86_seg_ldtr, tss.ldt, 0) )
|
|
|
4b77cf7 |
+ goto out;
|
|
|
4b77cf7 |
|
|
|
4b77cf7 |
if ( hvm_set_cr3(tss.cr3) )
|
|
|
4b77cf7 |
goto out;
|
|
|
4b77cf7 |
@@ -3851,13 +3852,12 @@ void hvm_task_switch(
|
|
|
4b77cf7 |
}
|
|
|
4b77cf7 |
|
|
|
4b77cf7 |
exn_raised = 0;
|
|
|
4b77cf7 |
- if ( hvm_load_segment_selector(x86_seg_ldtr, tss.ldt) ||
|
|
|
4b77cf7 |
- hvm_load_segment_selector(x86_seg_es, tss.es) ||
|
|
|
4b77cf7 |
- hvm_load_segment_selector(x86_seg_cs, tss.cs) ||
|
|
|
4b77cf7 |
- hvm_load_segment_selector(x86_seg_ss, tss.ss) ||
|
|
|
4b77cf7 |
- hvm_load_segment_selector(x86_seg_ds, tss.ds) ||
|
|
|
4b77cf7 |
- hvm_load_segment_selector(x86_seg_fs, tss.fs) ||
|
|
|
4b77cf7 |
- hvm_load_segment_selector(x86_seg_gs, tss.gs) )
|
|
|
4b77cf7 |
+ if ( hvm_load_segment_selector(x86_seg_es, tss.es, tss.eflags) ||
|
|
|
4b77cf7 |
+ hvm_load_segment_selector(x86_seg_cs, tss.cs, tss.eflags) ||
|
|
|
4b77cf7 |
+ hvm_load_segment_selector(x86_seg_ss, tss.ss, tss.eflags) ||
|
|
|
4b77cf7 |
+ hvm_load_segment_selector(x86_seg_ds, tss.ds, tss.eflags) ||
|
|
|
4b77cf7 |
+ hvm_load_segment_selector(x86_seg_fs, tss.fs, tss.eflags) ||
|
|
|
4b77cf7 |
+ hvm_load_segment_selector(x86_seg_gs, tss.gs, tss.eflags) )
|
|
|
4b77cf7 |
exn_raised = 1;
|
|
|
4b77cf7 |
|
|
|
4b77cf7 |
rc = hvm_copy_to_guest_virt(
|