aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2012-06-07 10:03:42 -0400
committerAvi Kivity <avi@redhat.com>2012-07-09 07:19:01 -0400
commit79d5b4c3cd809c770d4bf9812635647016c56011 (patch)
tree4d79b468cc6316529e7d3753edc872c1d1cf9aec /arch
parent6d6eede4a0492c7478d44d7c8fae80c3bcf529d9 (diff)
KVM: x86 emulator: allow loading null SS in long mode
Null SS is valid in long mode; allow loading it. Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/emulate.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index db95a55d5936..fe4340f62137 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -1324,8 +1324,14 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
1324 goto load; 1324 goto load;
1325 } 1325 }
1326 1326
1327 /* NULL selector is not valid for TR, CS and SS */ 1327 rpl = selector & 3;
1328 if ((seg == VCPU_SREG_CS || seg == VCPU_SREG_SS || seg == VCPU_SREG_TR) 1328 cpl = ctxt->ops->cpl(ctxt);
1329
1330 /* NULL selector is not valid for TR, CS and SS (except for long mode) */
1331 if ((seg == VCPU_SREG_CS
1332 || (seg == VCPU_SREG_SS
1333 && (ctxt->mode != X86EMUL_MODE_PROT64 || rpl != cpl))
1334 || seg == VCPU_SREG_TR)
1329 && null_selector) 1335 && null_selector)
1330 goto exception; 1336 goto exception;
1331 1337
@@ -1352,9 +1358,7 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt,
1352 goto exception; 1358 goto exception;
1353 } 1359 }
1354 1360
1355 rpl = selector & 3;
1356 dpl = seg_desc.dpl; 1361 dpl = seg_desc.dpl;
1357 cpl = ctxt->ops->cpl(ctxt);
1358 1362
1359 switch (seg) { 1363 switch (seg) {
1360 case VCPU_SREG_SS: 1364 case VCPU_SREG_SS: