diff options
Diffstat (limited to 'arch/x86/kvm/emulate.c')
-rw-r--r-- | arch/x86/kvm/emulate.c | 250 |
1 files changed, 186 insertions, 64 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index a46207a05835..749f9fa38254 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -504,11 +504,6 @@ static void rsp_increment(struct x86_emulate_ctxt *ctxt, int inc) | |||
504 | masked_increment(reg_rmw(ctxt, VCPU_REGS_RSP), stack_mask(ctxt), inc); | 504 | masked_increment(reg_rmw(ctxt, VCPU_REGS_RSP), stack_mask(ctxt), inc); |
505 | } | 505 | } |
506 | 506 | ||
507 | static inline void jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) | ||
508 | { | ||
509 | register_address_increment(ctxt, &ctxt->_eip, rel); | ||
510 | } | ||
511 | |||
512 | static u32 desc_limit_scaled(struct desc_struct *desc) | 507 | static u32 desc_limit_scaled(struct desc_struct *desc) |
513 | { | 508 | { |
514 | u32 limit = get_desc_limit(desc); | 509 | u32 limit = get_desc_limit(desc); |
@@ -569,6 +564,38 @@ static int emulate_nm(struct x86_emulate_ctxt *ctxt) | |||
569 | return emulate_exception(ctxt, NM_VECTOR, 0, false); | 564 | return emulate_exception(ctxt, NM_VECTOR, 0, false); |
570 | } | 565 | } |
571 | 566 | ||
567 | static inline int assign_eip_far(struct x86_emulate_ctxt *ctxt, ulong dst, | ||
568 | int cs_l) | ||
569 | { | ||
570 | switch (ctxt->op_bytes) { | ||
571 | case 2: | ||
572 | ctxt->_eip = (u16)dst; | ||
573 | break; | ||
574 | case 4: | ||
575 | ctxt->_eip = (u32)dst; | ||
576 | break; | ||
577 | case 8: | ||
578 | if ((cs_l && is_noncanonical_address(dst)) || | ||
579 | (!cs_l && (dst & ~(u32)-1))) | ||
580 | return emulate_gp(ctxt, 0); | ||
581 | ctxt->_eip = dst; | ||
582 | break; | ||
583 | default: | ||
584 | WARN(1, "unsupported eip assignment size\n"); | ||
585 | } | ||
586 | return X86EMUL_CONTINUE; | ||
587 | } | ||
588 | |||
589 | static inline int assign_eip_near(struct x86_emulate_ctxt *ctxt, ulong dst) | ||
590 | { | ||
591 | return assign_eip_far(ctxt, dst, ctxt->mode == X86EMUL_MODE_PROT64); | ||
592 | } | ||
593 | |||
594 | static inline int jmp_rel(struct x86_emulate_ctxt *ctxt, int rel) | ||
595 | { | ||
596 | return assign_eip_near(ctxt, ctxt->_eip + rel); | ||
597 | } | ||
598 | |||
572 | static u16 get_segment_selector(struct x86_emulate_ctxt *ctxt, unsigned seg) | 599 | static u16 get_segment_selector(struct x86_emulate_ctxt *ctxt, unsigned seg) |
573 | { | 600 | { |
574 | u16 selector; | 601 | u16 selector; |
@@ -751,8 +778,10 @@ static int __do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size) | |||
751 | static __always_inline int do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, | 778 | static __always_inline int do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, |
752 | unsigned size) | 779 | unsigned size) |
753 | { | 780 | { |
754 | if (unlikely(ctxt->fetch.end - ctxt->fetch.ptr < size)) | 781 | unsigned done_size = ctxt->fetch.end - ctxt->fetch.ptr; |
755 | return __do_insn_fetch_bytes(ctxt, size); | 782 | |
783 | if (unlikely(done_size < size)) | ||
784 | return __do_insn_fetch_bytes(ctxt, size - done_size); | ||
756 | else | 785 | else |
757 | return X86EMUL_CONTINUE; | 786 | return X86EMUL_CONTINUE; |
758 | } | 787 | } |
@@ -1416,7 +1445,9 @@ static int write_segment_descriptor(struct x86_emulate_ctxt *ctxt, | |||
1416 | 1445 | ||
1417 | /* Does not support long mode */ | 1446 | /* Does not support long mode */ |
1418 | static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, | 1447 | static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, |
1419 | u16 selector, int seg, u8 cpl, bool in_task_switch) | 1448 | u16 selector, int seg, u8 cpl, |
1449 | bool in_task_switch, | ||
1450 | struct desc_struct *desc) | ||
1420 | { | 1451 | { |
1421 | struct desc_struct seg_desc, old_desc; | 1452 | struct desc_struct seg_desc, old_desc; |
1422 | u8 dpl, rpl; | 1453 | u8 dpl, rpl; |
@@ -1557,6 +1588,8 @@ static int __load_segment_descriptor(struct x86_emulate_ctxt *ctxt, | |||
1557 | } | 1588 | } |
1558 | load: | 1589 | load: |
1559 | ctxt->ops->set_segment(ctxt, selector, &seg_desc, base3, seg); | 1590 | ctxt->ops->set_segment(ctxt, selector, &seg_desc, base3, seg); |
1591 | if (desc) | ||
1592 | *desc = seg_desc; | ||
1560 | return X86EMUL_CONTINUE; | 1593 | return X86EMUL_CONTINUE; |
1561 | exception: | 1594 | exception: |
1562 | return emulate_exception(ctxt, err_vec, err_code, true); | 1595 | return emulate_exception(ctxt, err_vec, err_code, true); |
@@ -1566,7 +1599,7 @@ static int load_segment_descriptor(struct x86_emulate_ctxt *ctxt, | |||
1566 | u16 selector, int seg) | 1599 | u16 selector, int seg) |
1567 | { | 1600 | { |
1568 | u8 cpl = ctxt->ops->cpl(ctxt); | 1601 | u8 cpl = ctxt->ops->cpl(ctxt); |
1569 | return __load_segment_descriptor(ctxt, selector, seg, cpl, false); | 1602 | return __load_segment_descriptor(ctxt, selector, seg, cpl, false, NULL); |
1570 | } | 1603 | } |
1571 | 1604 | ||
1572 | static void write_register_operand(struct operand *op) | 1605 | static void write_register_operand(struct operand *op) |
@@ -1960,17 +1993,31 @@ static int em_iret(struct x86_emulate_ctxt *ctxt) | |||
1960 | static int em_jmp_far(struct x86_emulate_ctxt *ctxt) | 1993 | static int em_jmp_far(struct x86_emulate_ctxt *ctxt) |
1961 | { | 1994 | { |
1962 | int rc; | 1995 | int rc; |
1963 | unsigned short sel; | 1996 | unsigned short sel, old_sel; |
1997 | struct desc_struct old_desc, new_desc; | ||
1998 | const struct x86_emulate_ops *ops = ctxt->ops; | ||
1999 | u8 cpl = ctxt->ops->cpl(ctxt); | ||
2000 | |||
2001 | /* Assignment of RIP may only fail in 64-bit mode */ | ||
2002 | if (ctxt->mode == X86EMUL_MODE_PROT64) | ||
2003 | ops->get_segment(ctxt, &old_sel, &old_desc, NULL, | ||
2004 | VCPU_SREG_CS); | ||
1964 | 2005 | ||
1965 | memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2); | 2006 | memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2); |
1966 | 2007 | ||
1967 | rc = load_segment_descriptor(ctxt, sel, VCPU_SREG_CS); | 2008 | rc = __load_segment_descriptor(ctxt, sel, VCPU_SREG_CS, cpl, false, |
2009 | &new_desc); | ||
1968 | if (rc != X86EMUL_CONTINUE) | 2010 | if (rc != X86EMUL_CONTINUE) |
1969 | return rc; | 2011 | return rc; |
1970 | 2012 | ||
1971 | ctxt->_eip = 0; | 2013 | rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l); |
1972 | memcpy(&ctxt->_eip, ctxt->src.valptr, ctxt->op_bytes); | 2014 | if (rc != X86EMUL_CONTINUE) { |
1973 | return X86EMUL_CONTINUE; | 2015 | WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64); |
2016 | /* assigning eip failed; restore the old cs */ | ||
2017 | ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS); | ||
2018 | return rc; | ||
2019 | } | ||
2020 | return rc; | ||
1974 | } | 2021 | } |
1975 | 2022 | ||
1976 | static int em_grp45(struct x86_emulate_ctxt *ctxt) | 2023 | static int em_grp45(struct x86_emulate_ctxt *ctxt) |
@@ -1981,13 +2028,15 @@ static int em_grp45(struct x86_emulate_ctxt *ctxt) | |||
1981 | case 2: /* call near abs */ { | 2028 | case 2: /* call near abs */ { |
1982 | long int old_eip; | 2029 | long int old_eip; |
1983 | old_eip = ctxt->_eip; | 2030 | old_eip = ctxt->_eip; |
1984 | ctxt->_eip = ctxt->src.val; | 2031 | rc = assign_eip_near(ctxt, ctxt->src.val); |
2032 | if (rc != X86EMUL_CONTINUE) | ||
2033 | break; | ||
1985 | ctxt->src.val = old_eip; | 2034 | ctxt->src.val = old_eip; |
1986 | rc = em_push(ctxt); | 2035 | rc = em_push(ctxt); |
1987 | break; | 2036 | break; |
1988 | } | 2037 | } |
1989 | case 4: /* jmp abs */ | 2038 | case 4: /* jmp abs */ |
1990 | ctxt->_eip = ctxt->src.val; | 2039 | rc = assign_eip_near(ctxt, ctxt->src.val); |
1991 | break; | 2040 | break; |
1992 | case 5: /* jmp far */ | 2041 | case 5: /* jmp far */ |
1993 | rc = em_jmp_far(ctxt); | 2042 | rc = em_jmp_far(ctxt); |
@@ -2022,30 +2071,47 @@ static int em_cmpxchg8b(struct x86_emulate_ctxt *ctxt) | |||
2022 | 2071 | ||
2023 | static int em_ret(struct x86_emulate_ctxt *ctxt) | 2072 | static int em_ret(struct x86_emulate_ctxt *ctxt) |
2024 | { | 2073 | { |
2025 | ctxt->dst.type = OP_REG; | 2074 | int rc; |
2026 | ctxt->dst.addr.reg = &ctxt->_eip; | 2075 | unsigned long eip; |
2027 | ctxt->dst.bytes = ctxt->op_bytes; | 2076 | |
2028 | return em_pop(ctxt); | 2077 | rc = emulate_pop(ctxt, &eip, ctxt->op_bytes); |
2078 | if (rc != X86EMUL_CONTINUE) | ||
2079 | return rc; | ||
2080 | |||
2081 | return assign_eip_near(ctxt, eip); | ||
2029 | } | 2082 | } |
2030 | 2083 | ||
2031 | static int em_ret_far(struct x86_emulate_ctxt *ctxt) | 2084 | static int em_ret_far(struct x86_emulate_ctxt *ctxt) |
2032 | { | 2085 | { |
2033 | int rc; | 2086 | int rc; |
2034 | unsigned long cs; | 2087 | unsigned long eip, cs; |
2088 | u16 old_cs; | ||
2035 | int cpl = ctxt->ops->cpl(ctxt); | 2089 | int cpl = ctxt->ops->cpl(ctxt); |
2090 | struct desc_struct old_desc, new_desc; | ||
2091 | const struct x86_emulate_ops *ops = ctxt->ops; | ||
2036 | 2092 | ||
2037 | rc = emulate_pop(ctxt, &ctxt->_eip, ctxt->op_bytes); | 2093 | if (ctxt->mode == X86EMUL_MODE_PROT64) |
2094 | ops->get_segment(ctxt, &old_cs, &old_desc, NULL, | ||
2095 | VCPU_SREG_CS); | ||
2096 | |||
2097 | rc = emulate_pop(ctxt, &eip, ctxt->op_bytes); | ||
2038 | if (rc != X86EMUL_CONTINUE) | 2098 | if (rc != X86EMUL_CONTINUE) |
2039 | return rc; | 2099 | return rc; |
2040 | if (ctxt->op_bytes == 4) | ||
2041 | ctxt->_eip = (u32)ctxt->_eip; | ||
2042 | rc = emulate_pop(ctxt, &cs, ctxt->op_bytes); | 2100 | rc = emulate_pop(ctxt, &cs, ctxt->op_bytes); |
2043 | if (rc != X86EMUL_CONTINUE) | 2101 | if (rc != X86EMUL_CONTINUE) |
2044 | return rc; | 2102 | return rc; |
2045 | /* Outer-privilege level return is not implemented */ | 2103 | /* Outer-privilege level return is not implemented */ |
2046 | if (ctxt->mode >= X86EMUL_MODE_PROT16 && (cs & 3) > cpl) | 2104 | if (ctxt->mode >= X86EMUL_MODE_PROT16 && (cs & 3) > cpl) |
2047 | return X86EMUL_UNHANDLEABLE; | 2105 | return X86EMUL_UNHANDLEABLE; |
2048 | rc = load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS); | 2106 | rc = __load_segment_descriptor(ctxt, (u16)cs, VCPU_SREG_CS, 0, false, |
2107 | &new_desc); | ||
2108 | if (rc != X86EMUL_CONTINUE) | ||
2109 | return rc; | ||
2110 | rc = assign_eip_far(ctxt, eip, new_desc.l); | ||
2111 | if (rc != X86EMUL_CONTINUE) { | ||
2112 | WARN_ON(!ctxt->mode != X86EMUL_MODE_PROT64); | ||
2113 | ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS); | ||
2114 | } | ||
2049 | return rc; | 2115 | return rc; |
2050 | } | 2116 | } |
2051 | 2117 | ||
@@ -2306,7 +2372,7 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt) | |||
2306 | { | 2372 | { |
2307 | const struct x86_emulate_ops *ops = ctxt->ops; | 2373 | const struct x86_emulate_ops *ops = ctxt->ops; |
2308 | struct desc_struct cs, ss; | 2374 | struct desc_struct cs, ss; |
2309 | u64 msr_data; | 2375 | u64 msr_data, rcx, rdx; |
2310 | int usermode; | 2376 | int usermode; |
2311 | u16 cs_sel = 0, ss_sel = 0; | 2377 | u16 cs_sel = 0, ss_sel = 0; |
2312 | 2378 | ||
@@ -2322,6 +2388,9 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt) | |||
2322 | else | 2388 | else |
2323 | usermode = X86EMUL_MODE_PROT32; | 2389 | usermode = X86EMUL_MODE_PROT32; |
2324 | 2390 | ||
2391 | rcx = reg_read(ctxt, VCPU_REGS_RCX); | ||
2392 | rdx = reg_read(ctxt, VCPU_REGS_RDX); | ||
2393 | |||
2325 | cs.dpl = 3; | 2394 | cs.dpl = 3; |
2326 | ss.dpl = 3; | 2395 | ss.dpl = 3; |
2327 | ops->get_msr(ctxt, MSR_IA32_SYSENTER_CS, &msr_data); | 2396 | ops->get_msr(ctxt, MSR_IA32_SYSENTER_CS, &msr_data); |
@@ -2339,6 +2408,9 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt) | |||
2339 | ss_sel = cs_sel + 8; | 2408 | ss_sel = cs_sel + 8; |
2340 | cs.d = 0; | 2409 | cs.d = 0; |
2341 | cs.l = 1; | 2410 | cs.l = 1; |
2411 | if (is_noncanonical_address(rcx) || | ||
2412 | is_noncanonical_address(rdx)) | ||
2413 | return emulate_gp(ctxt, 0); | ||
2342 | break; | 2414 | break; |
2343 | } | 2415 | } |
2344 | cs_sel |= SELECTOR_RPL_MASK; | 2416 | cs_sel |= SELECTOR_RPL_MASK; |
@@ -2347,8 +2419,8 @@ static int em_sysexit(struct x86_emulate_ctxt *ctxt) | |||
2347 | ops->set_segment(ctxt, cs_sel, &cs, 0, VCPU_SREG_CS); | 2419 | ops->set_segment(ctxt, cs_sel, &cs, 0, VCPU_SREG_CS); |
2348 | ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS); | 2420 | ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS); |
2349 | 2421 | ||
2350 | ctxt->_eip = reg_read(ctxt, VCPU_REGS_RDX); | 2422 | ctxt->_eip = rdx; |
2351 | *reg_write(ctxt, VCPU_REGS_RSP) = reg_read(ctxt, VCPU_REGS_RCX); | 2423 | *reg_write(ctxt, VCPU_REGS_RSP) = rcx; |
2352 | 2424 | ||
2353 | return X86EMUL_CONTINUE; | 2425 | return X86EMUL_CONTINUE; |
2354 | } | 2426 | } |
@@ -2466,19 +2538,24 @@ static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt, | |||
2466 | * Now load segment descriptors. If fault happens at this stage | 2538 | * Now load segment descriptors. If fault happens at this stage |
2467 | * it is handled in a context of new task | 2539 | * it is handled in a context of new task |
2468 | */ | 2540 | */ |
2469 | ret = __load_segment_descriptor(ctxt, tss->ldt, VCPU_SREG_LDTR, cpl, true); | 2541 | ret = __load_segment_descriptor(ctxt, tss->ldt, VCPU_SREG_LDTR, cpl, |
2542 | true, NULL); | ||
2470 | if (ret != X86EMUL_CONTINUE) | 2543 | if (ret != X86EMUL_CONTINUE) |
2471 | return ret; | 2544 | return ret; |
2472 | ret = __load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, cpl, true); | 2545 | ret = __load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, cpl, |
2546 | true, NULL); | ||
2473 | if (ret != X86EMUL_CONTINUE) | 2547 | if (ret != X86EMUL_CONTINUE) |
2474 | return ret; | 2548 | return ret; |
2475 | ret = __load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, cpl, true); | 2549 | ret = __load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, cpl, |
2550 | true, NULL); | ||
2476 | if (ret != X86EMUL_CONTINUE) | 2551 | if (ret != X86EMUL_CONTINUE) |
2477 | return ret; | 2552 | return ret; |
2478 | ret = __load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, cpl, true); | 2553 | ret = __load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, cpl, |
2554 | true, NULL); | ||
2479 | if (ret != X86EMUL_CONTINUE) | 2555 | if (ret != X86EMUL_CONTINUE) |
2480 | return ret; | 2556 | return ret; |
2481 | ret = __load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, cpl, true); | 2557 | ret = __load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, cpl, |
2558 | true, NULL); | ||
2482 | if (ret != X86EMUL_CONTINUE) | 2559 | if (ret != X86EMUL_CONTINUE) |
2483 | return ret; | 2560 | return ret; |
2484 | 2561 | ||
@@ -2603,25 +2680,32 @@ static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt, | |||
2603 | * Now load segment descriptors. If fault happenes at this stage | 2680 | * Now load segment descriptors. If fault happenes at this stage |
2604 | * it is handled in a context of new task | 2681 | * it is handled in a context of new task |
2605 | */ | 2682 | */ |
2606 | ret = __load_segment_descriptor(ctxt, tss->ldt_selector, VCPU_SREG_LDTR, cpl, true); | 2683 | ret = __load_segment_descriptor(ctxt, tss->ldt_selector, VCPU_SREG_LDTR, |
2684 | cpl, true, NULL); | ||
2607 | if (ret != X86EMUL_CONTINUE) | 2685 | if (ret != X86EMUL_CONTINUE) |
2608 | return ret; | 2686 | return ret; |
2609 | ret = __load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, cpl, true); | 2687 | ret = __load_segment_descriptor(ctxt, tss->es, VCPU_SREG_ES, cpl, |
2688 | true, NULL); | ||
2610 | if (ret != X86EMUL_CONTINUE) | 2689 | if (ret != X86EMUL_CONTINUE) |
2611 | return ret; | 2690 | return ret; |
2612 | ret = __load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, cpl, true); | 2691 | ret = __load_segment_descriptor(ctxt, tss->cs, VCPU_SREG_CS, cpl, |
2692 | true, NULL); | ||
2613 | if (ret != X86EMUL_CONTINUE) | 2693 | if (ret != X86EMUL_CONTINUE) |
2614 | return ret; | 2694 | return ret; |
2615 | ret = __load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, cpl, true); | 2695 | ret = __load_segment_descriptor(ctxt, tss->ss, VCPU_SREG_SS, cpl, |
2696 | true, NULL); | ||
2616 | if (ret != X86EMUL_CONTINUE) | 2697 | if (ret != X86EMUL_CONTINUE) |
2617 | return ret; | 2698 | return ret; |
2618 | ret = __load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, cpl, true); | 2699 | ret = __load_segment_descriptor(ctxt, tss->ds, VCPU_SREG_DS, cpl, |
2700 | true, NULL); | ||
2619 | if (ret != X86EMUL_CONTINUE) | 2701 | if (ret != X86EMUL_CONTINUE) |
2620 | return ret; | 2702 | return ret; |
2621 | ret = __load_segment_descriptor(ctxt, tss->fs, VCPU_SREG_FS, cpl, true); | 2703 | ret = __load_segment_descriptor(ctxt, tss->fs, VCPU_SREG_FS, cpl, |
2704 | true, NULL); | ||
2622 | if (ret != X86EMUL_CONTINUE) | 2705 | if (ret != X86EMUL_CONTINUE) |
2623 | return ret; | 2706 | return ret; |
2624 | ret = __load_segment_descriptor(ctxt, tss->gs, VCPU_SREG_GS, cpl, true); | 2707 | ret = __load_segment_descriptor(ctxt, tss->gs, VCPU_SREG_GS, cpl, |
2708 | true, NULL); | ||
2625 | if (ret != X86EMUL_CONTINUE) | 2709 | if (ret != X86EMUL_CONTINUE) |
2626 | return ret; | 2710 | return ret; |
2627 | 2711 | ||
@@ -2888,10 +2972,13 @@ static int em_aad(struct x86_emulate_ctxt *ctxt) | |||
2888 | 2972 | ||
2889 | static int em_call(struct x86_emulate_ctxt *ctxt) | 2973 | static int em_call(struct x86_emulate_ctxt *ctxt) |
2890 | { | 2974 | { |
2975 | int rc; | ||
2891 | long rel = ctxt->src.val; | 2976 | long rel = ctxt->src.val; |
2892 | 2977 | ||
2893 | ctxt->src.val = (unsigned long)ctxt->_eip; | 2978 | ctxt->src.val = (unsigned long)ctxt->_eip; |
2894 | jmp_rel(ctxt, rel); | 2979 | rc = jmp_rel(ctxt, rel); |
2980 | if (rc != X86EMUL_CONTINUE) | ||
2981 | return rc; | ||
2895 | return em_push(ctxt); | 2982 | return em_push(ctxt); |
2896 | } | 2983 | } |
2897 | 2984 | ||
@@ -2900,34 +2987,50 @@ static int em_call_far(struct x86_emulate_ctxt *ctxt) | |||
2900 | u16 sel, old_cs; | 2987 | u16 sel, old_cs; |
2901 | ulong old_eip; | 2988 | ulong old_eip; |
2902 | int rc; | 2989 | int rc; |
2990 | struct desc_struct old_desc, new_desc; | ||
2991 | const struct x86_emulate_ops *ops = ctxt->ops; | ||
2992 | int cpl = ctxt->ops->cpl(ctxt); | ||
2903 | 2993 | ||
2904 | old_cs = get_segment_selector(ctxt, VCPU_SREG_CS); | ||
2905 | old_eip = ctxt->_eip; | 2994 | old_eip = ctxt->_eip; |
2995 | ops->get_segment(ctxt, &old_cs, &old_desc, NULL, VCPU_SREG_CS); | ||
2906 | 2996 | ||
2907 | memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2); | 2997 | memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2); |
2908 | if (load_segment_descriptor(ctxt, sel, VCPU_SREG_CS)) | 2998 | rc = __load_segment_descriptor(ctxt, sel, VCPU_SREG_CS, cpl, false, |
2999 | &new_desc); | ||
3000 | if (rc != X86EMUL_CONTINUE) | ||
2909 | return X86EMUL_CONTINUE; | 3001 | return X86EMUL_CONTINUE; |
2910 | 3002 | ||
2911 | ctxt->_eip = 0; | 3003 | rc = assign_eip_far(ctxt, ctxt->src.val, new_desc.l); |
2912 | memcpy(&ctxt->_eip, ctxt->src.valptr, ctxt->op_bytes); | 3004 | if (rc != X86EMUL_CONTINUE) |
3005 | goto fail; | ||
2913 | 3006 | ||
2914 | ctxt->src.val = old_cs; | 3007 | ctxt->src.val = old_cs; |
2915 | rc = em_push(ctxt); | 3008 | rc = em_push(ctxt); |
2916 | if (rc != X86EMUL_CONTINUE) | 3009 | if (rc != X86EMUL_CONTINUE) |
2917 | return rc; | 3010 | goto fail; |
2918 | 3011 | ||
2919 | ctxt->src.val = old_eip; | 3012 | ctxt->src.val = old_eip; |
2920 | return em_push(ctxt); | 3013 | rc = em_push(ctxt); |
3014 | /* If we failed, we tainted the memory, but the very least we should | ||
3015 | restore cs */ | ||
3016 | if (rc != X86EMUL_CONTINUE) | ||
3017 | goto fail; | ||
3018 | return rc; | ||
3019 | fail: | ||
3020 | ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS); | ||
3021 | return rc; | ||
3022 | |||
2921 | } | 3023 | } |
2922 | 3024 | ||
2923 | static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt) | 3025 | static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt) |
2924 | { | 3026 | { |
2925 | int rc; | 3027 | int rc; |
3028 | unsigned long eip; | ||
2926 | 3029 | ||
2927 | ctxt->dst.type = OP_REG; | 3030 | rc = emulate_pop(ctxt, &eip, ctxt->op_bytes); |
2928 | ctxt->dst.addr.reg = &ctxt->_eip; | 3031 | if (rc != X86EMUL_CONTINUE) |
2929 | ctxt->dst.bytes = ctxt->op_bytes; | 3032 | return rc; |
2930 | rc = emulate_pop(ctxt, &ctxt->dst.val, ctxt->op_bytes); | 3033 | rc = assign_eip_near(ctxt, eip); |
2931 | if (rc != X86EMUL_CONTINUE) | 3034 | if (rc != X86EMUL_CONTINUE) |
2932 | return rc; | 3035 | return rc; |
2933 | rsp_increment(ctxt, ctxt->src.val); | 3036 | rsp_increment(ctxt, ctxt->src.val); |
@@ -3254,20 +3357,24 @@ static int em_lmsw(struct x86_emulate_ctxt *ctxt) | |||
3254 | 3357 | ||
3255 | static int em_loop(struct x86_emulate_ctxt *ctxt) | 3358 | static int em_loop(struct x86_emulate_ctxt *ctxt) |
3256 | { | 3359 | { |
3360 | int rc = X86EMUL_CONTINUE; | ||
3361 | |||
3257 | register_address_increment(ctxt, reg_rmw(ctxt, VCPU_REGS_RCX), -1); | 3362 | register_address_increment(ctxt, reg_rmw(ctxt, VCPU_REGS_RCX), -1); |
3258 | if ((address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) != 0) && | 3363 | if ((address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) != 0) && |
3259 | (ctxt->b == 0xe2 || test_cc(ctxt->b ^ 0x5, ctxt->eflags))) | 3364 | (ctxt->b == 0xe2 || test_cc(ctxt->b ^ 0x5, ctxt->eflags))) |
3260 | jmp_rel(ctxt, ctxt->src.val); | 3365 | rc = jmp_rel(ctxt, ctxt->src.val); |
3261 | 3366 | ||
3262 | return X86EMUL_CONTINUE; | 3367 | return rc; |
3263 | } | 3368 | } |
3264 | 3369 | ||
3265 | static int em_jcxz(struct x86_emulate_ctxt *ctxt) | 3370 | static int em_jcxz(struct x86_emulate_ctxt *ctxt) |
3266 | { | 3371 | { |
3372 | int rc = X86EMUL_CONTINUE; | ||
3373 | |||
3267 | if (address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) == 0) | 3374 | if (address_mask(ctxt, reg_read(ctxt, VCPU_REGS_RCX)) == 0) |
3268 | jmp_rel(ctxt, ctxt->src.val); | 3375 | rc = jmp_rel(ctxt, ctxt->src.val); |
3269 | 3376 | ||
3270 | return X86EMUL_CONTINUE; | 3377 | return rc; |
3271 | } | 3378 | } |
3272 | 3379 | ||
3273 | static int em_in(struct x86_emulate_ctxt *ctxt) | 3380 | static int em_in(struct x86_emulate_ctxt *ctxt) |
@@ -3355,6 +3462,12 @@ static int em_bswap(struct x86_emulate_ctxt *ctxt) | |||
3355 | return X86EMUL_CONTINUE; | 3462 | return X86EMUL_CONTINUE; |
3356 | } | 3463 | } |
3357 | 3464 | ||
3465 | static int em_clflush(struct x86_emulate_ctxt *ctxt) | ||
3466 | { | ||
3467 | /* emulating clflush regardless of cpuid */ | ||
3468 | return X86EMUL_CONTINUE; | ||
3469 | } | ||
3470 | |||
3358 | static bool valid_cr(int nr) | 3471 | static bool valid_cr(int nr) |
3359 | { | 3472 | { |
3360 | switch (nr) { | 3473 | switch (nr) { |
@@ -3693,6 +3806,16 @@ static const struct opcode group11[] = { | |||
3693 | X7(D(Undefined)), | 3806 | X7(D(Undefined)), |
3694 | }; | 3807 | }; |
3695 | 3808 | ||
3809 | static const struct gprefix pfx_0f_ae_7 = { | ||
3810 | I(SrcMem | ByteOp, em_clflush), N, N, N, | ||
3811 | }; | ||
3812 | |||
3813 | static const struct group_dual group15 = { { | ||
3814 | N, N, N, N, N, N, N, GP(0, &pfx_0f_ae_7), | ||
3815 | }, { | ||
3816 | N, N, N, N, N, N, N, N, | ||
3817 | } }; | ||
3818 | |||
3696 | static const struct gprefix pfx_0f_6f_0f_7f = { | 3819 | static const struct gprefix pfx_0f_6f_0f_7f = { |
3697 | I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov), | 3820 | I(Mmx, em_mov), I(Sse | Aligned, em_mov), N, I(Sse | Unaligned, em_mov), |
3698 | }; | 3821 | }; |
@@ -3901,10 +4024,11 @@ static const struct opcode twobyte_table[256] = { | |||
3901 | N, I(ImplicitOps | EmulateOnUD, em_syscall), | 4024 | N, I(ImplicitOps | EmulateOnUD, em_syscall), |
3902 | II(ImplicitOps | Priv, em_clts, clts), N, | 4025 | II(ImplicitOps | Priv, em_clts, clts), N, |
3903 | DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N, | 4026 | DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N, |
3904 | N, D(ImplicitOps | ModRM), N, N, | 4027 | N, D(ImplicitOps | ModRM | SrcMem | NoAccess), N, N, |
3905 | /* 0x10 - 0x1F */ | 4028 | /* 0x10 - 0x1F */ |
3906 | N, N, N, N, N, N, N, N, | 4029 | N, N, N, N, N, N, N, N, |
3907 | D(ImplicitOps | ModRM), N, N, N, N, N, N, D(ImplicitOps | ModRM), | 4030 | D(ImplicitOps | ModRM | SrcMem | NoAccess), |
4031 | N, N, N, N, N, N, D(ImplicitOps | ModRM | SrcMem | NoAccess), | ||
3908 | /* 0x20 - 0x2F */ | 4032 | /* 0x20 - 0x2F */ |
3909 | DIP(ModRM | DstMem | Priv | Op3264 | NoMod, cr_read, check_cr_read), | 4033 | DIP(ModRM | DstMem | Priv | Op3264 | NoMod, cr_read, check_cr_read), |
3910 | DIP(ModRM | DstMem | Priv | Op3264 | NoMod, dr_read, check_dr_read), | 4034 | DIP(ModRM | DstMem | Priv | Op3264 | NoMod, dr_read, check_dr_read), |
@@ -3956,7 +4080,7 @@ static const struct opcode twobyte_table[256] = { | |||
3956 | F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts), | 4080 | F(DstMem | SrcReg | ModRM | BitOp | Lock | PageTable, em_bts), |
3957 | F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd), | 4081 | F(DstMem | SrcReg | Src2ImmByte | ModRM, em_shrd), |
3958 | F(DstMem | SrcReg | Src2CL | ModRM, em_shrd), | 4082 | F(DstMem | SrcReg | Src2CL | ModRM, em_shrd), |
3959 | D(ModRM), F(DstReg | SrcMem | ModRM, em_imul), | 4083 | GD(0, &group15), F(DstReg | SrcMem | ModRM, em_imul), |
3960 | /* 0xB0 - 0xB7 */ | 4084 | /* 0xB0 - 0xB7 */ |
3961 | I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_cmpxchg), | 4085 | I2bv(DstMem | SrcReg | ModRM | Lock | PageTable, em_cmpxchg), |
3962 | I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg), | 4086 | I(DstReg | SrcMemFAddr | ModRM | Src2SS, em_lseg), |
@@ -4473,10 +4597,10 @@ done_prefixes: | |||
4473 | /* Decode and fetch the destination operand: register or memory. */ | 4597 | /* Decode and fetch the destination operand: register or memory. */ |
4474 | rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask); | 4598 | rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask); |
4475 | 4599 | ||
4476 | done: | ||
4477 | if (ctxt->rip_relative) | 4600 | if (ctxt->rip_relative) |
4478 | ctxt->memopp->addr.mem.ea += ctxt->_eip; | 4601 | ctxt->memopp->addr.mem.ea += ctxt->_eip; |
4479 | 4602 | ||
4603 | done: | ||
4480 | return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK; | 4604 | return (rc != X86EMUL_CONTINUE) ? EMULATION_FAILED : EMULATION_OK; |
4481 | } | 4605 | } |
4482 | 4606 | ||
@@ -4726,7 +4850,7 @@ special_insn: | |||
4726 | break; | 4850 | break; |
4727 | case 0x70 ... 0x7f: /* jcc (short) */ | 4851 | case 0x70 ... 0x7f: /* jcc (short) */ |
4728 | if (test_cc(ctxt->b, ctxt->eflags)) | 4852 | if (test_cc(ctxt->b, ctxt->eflags)) |
4729 | jmp_rel(ctxt, ctxt->src.val); | 4853 | rc = jmp_rel(ctxt, ctxt->src.val); |
4730 | break; | 4854 | break; |
4731 | case 0x8d: /* lea r16/r32, m */ | 4855 | case 0x8d: /* lea r16/r32, m */ |
4732 | ctxt->dst.val = ctxt->src.addr.mem.ea; | 4856 | ctxt->dst.val = ctxt->src.addr.mem.ea; |
@@ -4756,7 +4880,7 @@ special_insn: | |||
4756 | break; | 4880 | break; |
4757 | case 0xe9: /* jmp rel */ | 4881 | case 0xe9: /* jmp rel */ |
4758 | case 0xeb: /* jmp rel short */ | 4882 | case 0xeb: /* jmp rel short */ |
4759 | jmp_rel(ctxt, ctxt->src.val); | 4883 | rc = jmp_rel(ctxt, ctxt->src.val); |
4760 | ctxt->dst.type = OP_NONE; /* Disable writeback. */ | 4884 | ctxt->dst.type = OP_NONE; /* Disable writeback. */ |
4761 | break; | 4885 | break; |
4762 | case 0xf4: /* hlt */ | 4886 | case 0xf4: /* hlt */ |
@@ -4881,13 +5005,11 @@ twobyte_insn: | |||
4881 | break; | 5005 | break; |
4882 | case 0x80 ... 0x8f: /* jnz rel, etc*/ | 5006 | case 0x80 ... 0x8f: /* jnz rel, etc*/ |
4883 | if (test_cc(ctxt->b, ctxt->eflags)) | 5007 | if (test_cc(ctxt->b, ctxt->eflags)) |
4884 | jmp_rel(ctxt, ctxt->src.val); | 5008 | rc = jmp_rel(ctxt, ctxt->src.val); |
4885 | break; | 5009 | break; |
4886 | case 0x90 ... 0x9f: /* setcc r/m8 */ | 5010 | case 0x90 ... 0x9f: /* setcc r/m8 */ |
4887 | ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags); | 5011 | ctxt->dst.val = test_cc(ctxt->b, ctxt->eflags); |
4888 | break; | 5012 | break; |
4889 | case 0xae: /* clflush */ | ||
4890 | break; | ||
4891 | case 0xb6 ... 0xb7: /* movzx */ | 5013 | case 0xb6 ... 0xb7: /* movzx */ |
4892 | ctxt->dst.bytes = ctxt->op_bytes; | 5014 | ctxt->dst.bytes = ctxt->op_bytes; |
4893 | ctxt->dst.val = (ctxt->src.bytes == 1) ? (u8) ctxt->src.val | 5015 | ctxt->dst.val = (ctxt->src.bytes == 1) ? (u8) ctxt->src.val |