diff options
author | Avi Kivity <avi@qumranet.com> | 2008-04-14 07:40:50 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-04-27 11:21:34 -0400 |
commit | 16286d082d99cb41e16938fa6ba84604229f4b77 (patch) | |
tree | 4320f07eea5e48e617c03d732b178d9d99f81f41 /arch | |
parent | 66b85505736dbd3a3a0ed5ae38c12bb218b231c0 (diff) |
KVM: x86 emulator: fix smsw and lmsw with a memory operand
lmsw and smsw were implemented only with a register operand. Extend them
to support a memory operand as well. Fixes Windows running some display
compatibility test on AMD hosts.
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/x86_emulate.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 8e1b32f2cd5e..46ef78f8bb35 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c | |||
@@ -275,12 +275,15 @@ static u16 group_table[] = { | |||
275 | SrcMem | ModRM, 0, SrcMem | ModRM | Stack, 0, | 275 | SrcMem | ModRM, 0, SrcMem | ModRM | Stack, 0, |
276 | [Group7*8] = | 276 | [Group7*8] = |
277 | 0, 0, ModRM | SrcMem, ModRM | SrcMem, | 277 | 0, 0, ModRM | SrcMem, ModRM | SrcMem, |
278 | SrcNone | ModRM | DstMem, 0, SrcMem | ModRM, SrcMem | ModRM | ByteOp, | 278 | SrcNone | ModRM | DstMem | Mov, 0, |
279 | SrcMem16 | ModRM | Mov, SrcMem | ModRM | ByteOp, | ||
279 | }; | 280 | }; |
280 | 281 | ||
281 | static u16 group2_table[] = { | 282 | static u16 group2_table[] = { |
282 | [Group7*8] = | 283 | [Group7*8] = |
283 | SrcNone | ModRM, 0, 0, 0, SrcNone | ModRM | DstMem, 0, SrcMem | ModRM, 0, | 284 | SrcNone | ModRM, 0, 0, 0, |
285 | SrcNone | ModRM | DstMem | Mov, 0, | ||
286 | SrcMem16 | ModRM | Mov, 0, | ||
284 | }; | 287 | }; |
285 | 288 | ||
286 | /* EFLAGS bit definitions. */ | 289 | /* EFLAGS bit definitions. */ |
@@ -1722,6 +1725,8 @@ twobyte_insn: | |||
1722 | goto done; | 1725 | goto done; |
1723 | 1726 | ||
1724 | kvm_emulate_hypercall(ctxt->vcpu); | 1727 | kvm_emulate_hypercall(ctxt->vcpu); |
1728 | /* Disable writeback. */ | ||
1729 | c->dst.type = OP_NONE; | ||
1725 | break; | 1730 | break; |
1726 | case 2: /* lgdt */ | 1731 | case 2: /* lgdt */ |
1727 | rc = read_descriptor(ctxt, ops, c->src.ptr, | 1732 | rc = read_descriptor(ctxt, ops, c->src.ptr, |
@@ -1729,6 +1734,8 @@ twobyte_insn: | |||
1729 | if (rc) | 1734 | if (rc) |
1730 | goto done; | 1735 | goto done; |
1731 | realmode_lgdt(ctxt->vcpu, size, address); | 1736 | realmode_lgdt(ctxt->vcpu, size, address); |
1737 | /* Disable writeback. */ | ||
1738 | c->dst.type = OP_NONE; | ||
1732 | break; | 1739 | break; |
1733 | case 3: /* lidt/vmmcall */ | 1740 | case 3: /* lidt/vmmcall */ |
1734 | if (c->modrm_mod == 3 && c->modrm_rm == 1) { | 1741 | if (c->modrm_mod == 3 && c->modrm_rm == 1) { |
@@ -1744,27 +1751,25 @@ twobyte_insn: | |||
1744 | goto done; | 1751 | goto done; |
1745 | realmode_lidt(ctxt->vcpu, size, address); | 1752 | realmode_lidt(ctxt->vcpu, size, address); |
1746 | } | 1753 | } |
1754 | /* Disable writeback. */ | ||
1755 | c->dst.type = OP_NONE; | ||
1747 | break; | 1756 | break; |
1748 | case 4: /* smsw */ | 1757 | case 4: /* smsw */ |
1749 | if (c->modrm_mod != 3) | 1758 | c->dst.bytes = 2; |
1750 | goto cannot_emulate; | 1759 | c->dst.val = realmode_get_cr(ctxt->vcpu, 0); |
1751 | *(u16 *)&c->regs[c->modrm_rm] | ||
1752 | = realmode_get_cr(ctxt->vcpu, 0); | ||
1753 | break; | 1760 | break; |
1754 | case 6: /* lmsw */ | 1761 | case 6: /* lmsw */ |
1755 | if (c->modrm_mod != 3) | 1762 | realmode_lmsw(ctxt->vcpu, (u16)c->src.val, |
1756 | goto cannot_emulate; | 1763 | &ctxt->eflags); |
1757 | realmode_lmsw(ctxt->vcpu, (u16)c->modrm_val, | ||
1758 | &ctxt->eflags); | ||
1759 | break; | 1764 | break; |
1760 | case 7: /* invlpg*/ | 1765 | case 7: /* invlpg*/ |
1761 | emulate_invlpg(ctxt->vcpu, memop); | 1766 | emulate_invlpg(ctxt->vcpu, memop); |
1767 | /* Disable writeback. */ | ||
1768 | c->dst.type = OP_NONE; | ||
1762 | break; | 1769 | break; |
1763 | default: | 1770 | default: |
1764 | goto cannot_emulate; | 1771 | goto cannot_emulate; |
1765 | } | 1772 | } |
1766 | /* Disable writeback. */ | ||
1767 | c->dst.type = OP_NONE; | ||
1768 | break; | 1773 | break; |
1769 | case 0x06: | 1774 | case 0x06: |
1770 | emulate_clts(ctxt->vcpu); | 1775 | emulate_clts(ctxt->vcpu); |