aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/kvm/emulate.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 52a96270b560..5edf088ca51e 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -574,12 +574,14 @@ static inline int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst,
574 case 4: 574 case 4:
575 ctxt->_eip = (u32)dst; 575 ctxt->_eip = (u32)dst;
576 break; 576 break;
577#ifdef CONFIG_X86_64
577 case 8: 578 case 8:
578 if ((cs_l && is_noncanonical_address(dst)) || 579 if ((cs_l && is_noncanonical_address(dst)) ||
579 (!cs_l && (dst & ~(u32)-1))) 580 (!cs_l && (dst >> 32) != 0))
580 return emulate_gp(ctxt, 0); 581 return emulate_gp(ctxt, 0);
581 ctxt->_eip = dst; 582 ctxt->_eip = dst;
582 break; 583 break;
584#endif
583 default: 585 default:
584 WARN(1, "unsupported eip assignment size\n"); 586 WARN(1, "unsupported eip assignment size\n");
585 } 587 }
@@ -2035,7 +2037,7 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
2035 2037
2036 rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l); 2038 rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l);
2037 if (rc != X86EMUL_CONTINUE) { 2039 if (rc != X86EMUL_CONTINUE) {
2038 WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64); 2040 WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64);
2039 /* assigning eip failed; restore the old cs */ 2041 /* assigning eip failed; restore the old cs */
2040 ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS); 2042 ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS);
2041 return rc; 2043 return rc;
@@ -2132,7 +2134,7 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
2132 return rc; 2134 return rc;
2133 rc = assign_eip_far(ctxt, eip, new_desc.l); 2135 rc = assign_eip_far(ctxt, eip, new_desc.l);
2134 if (rc != X86EMUL_CONTINUE) { 2136 if (rc != X86EMUL_CONTINUE) {
2135 WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64); 2137 WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64);
2136 ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS); 2138 ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS);
2137 } 2139 }
2138 return rc; 2140 return rc;