diff options
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/emulate.c | 14 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 26 |
2 files changed, 19 insertions, 21 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 0ff7d4bd1bb..57e0e291b38 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -3494,6 +3494,7 @@ x86_emulate_insn(struct x86_emulate_ctxt *ctxt) | |||
3494 | int rc = X86EMUL_CONTINUE; | 3494 | int rc = X86EMUL_CONTINUE; |
3495 | int saved_dst_type = c->dst.type; | 3495 | int saved_dst_type = c->dst.type; |
3496 | int irq; /* Used for int 3, int, and into */ | 3496 | int irq; /* Used for int 3, int, and into */ |
3497 | struct desc_ptr desc_ptr; | ||
3497 | 3498 | ||
3498 | ctxt->decode.mem_read.pos = 0; | 3499 | ctxt->decode.mem_read.pos = 0; |
3499 | 3500 | ||
@@ -4005,9 +4006,6 @@ twobyte_insn: | |||
4005 | switch (c->b) { | 4006 | switch (c->b) { |
4006 | case 0x01: /* lgdt, lidt, lmsw */ | 4007 | case 0x01: /* lgdt, lidt, lmsw */ |
4007 | switch (c->modrm_reg) { | 4008 | switch (c->modrm_reg) { |
4008 | u16 size; | ||
4009 | unsigned long address; | ||
4010 | |||
4011 | case 0: /* vmcall */ | 4009 | case 0: /* vmcall */ |
4012 | if (c->modrm_mod != 3 || c->modrm_rm != 1) | 4010 | if (c->modrm_mod != 3 || c->modrm_rm != 1) |
4013 | goto cannot_emulate; | 4011 | goto cannot_emulate; |
@@ -4023,10 +4021,11 @@ twobyte_insn: | |||
4023 | break; | 4021 | break; |
4024 | case 2: /* lgdt */ | 4022 | case 2: /* lgdt */ |
4025 | rc = read_descriptor(ctxt, ops, c->src.addr.mem, | 4023 | rc = read_descriptor(ctxt, ops, c->src.addr.mem, |
4026 | &size, &address, c->op_bytes); | 4024 | &desc_ptr.size, &desc_ptr.address, |
4025 | c->op_bytes); | ||
4027 | if (rc != X86EMUL_CONTINUE) | 4026 | if (rc != X86EMUL_CONTINUE) |
4028 | goto done; | 4027 | goto done; |
4029 | realmode_lgdt(ctxt->vcpu, size, address); | 4028 | ctxt->ops->set_gdt(ctxt, &desc_ptr); |
4030 | /* Disable writeback. */ | 4029 | /* Disable writeback. */ |
4031 | c->dst.type = OP_NONE; | 4030 | c->dst.type = OP_NONE; |
4032 | break; | 4031 | break; |
@@ -4041,11 +4040,12 @@ twobyte_insn: | |||
4041 | } | 4040 | } |
4042 | } else { | 4041 | } else { |
4043 | rc = read_descriptor(ctxt, ops, c->src.addr.mem, | 4042 | rc = read_descriptor(ctxt, ops, c->src.addr.mem, |
4044 | &size, &address, | 4043 | &desc_ptr.size, |
4044 | &desc_ptr.address, | ||
4045 | c->op_bytes); | 4045 | c->op_bytes); |
4046 | if (rc != X86EMUL_CONTINUE) | 4046 | if (rc != X86EMUL_CONTINUE) |
4047 | goto done; | 4047 | goto done; |
4048 | realmode_lidt(ctxt->vcpu, size, address); | 4048 | ctxt->ops->set_idt(ctxt, &desc_ptr); |
4049 | } | 4049 | } |
4050 | /* Disable writeback. */ | 4050 | /* Disable writeback. */ |
4051 | c->dst.type = OP_NONE; | 4051 | c->dst.type = OP_NONE; |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4f7248ea6ca..7cd3a3b491d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -4249,6 +4249,16 @@ static void emulator_get_idt(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt) | |||
4249 | kvm_x86_ops->get_idt(emul_to_vcpu(ctxt), dt); | 4249 | kvm_x86_ops->get_idt(emul_to_vcpu(ctxt), dt); |
4250 | } | 4250 | } |
4251 | 4251 | ||
4252 | static void emulator_set_gdt(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt) | ||
4253 | { | ||
4254 | kvm_x86_ops->set_gdt(emul_to_vcpu(ctxt), dt); | ||
4255 | } | ||
4256 | |||
4257 | static void emulator_set_idt(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt) | ||
4258 | { | ||
4259 | kvm_x86_ops->set_idt(emul_to_vcpu(ctxt), dt); | ||
4260 | } | ||
4261 | |||
4252 | static unsigned long emulator_get_cached_segment_base( | 4262 | static unsigned long emulator_get_cached_segment_base( |
4253 | struct x86_emulate_ctxt *ctxt, int seg) | 4263 | struct x86_emulate_ctxt *ctxt, int seg) |
4254 | { | 4264 | { |
@@ -4388,6 +4398,8 @@ static struct x86_emulate_ops emulate_ops = { | |||
4388 | .get_cached_segment_base = emulator_get_cached_segment_base, | 4398 | .get_cached_segment_base = emulator_get_cached_segment_base, |
4389 | .get_gdt = emulator_get_gdt, | 4399 | .get_gdt = emulator_get_gdt, |
4390 | .get_idt = emulator_get_idt, | 4400 | .get_idt = emulator_get_idt, |
4401 | .set_gdt = emulator_set_gdt, | ||
4402 | .set_idt = emulator_set_idt, | ||
4391 | .get_cr = emulator_get_cr, | 4403 | .get_cr = emulator_get_cr, |
4392 | .set_cr = emulator_set_cr, | 4404 | .set_cr = emulator_set_cr, |
4393 | .cpl = emulator_get_cpl, | 4405 | .cpl = emulator_get_cpl, |
@@ -5049,20 +5061,6 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu) | |||
5049 | rip, instruction, 3, NULL); | 5061 | rip, instruction, 3, NULL); |
5050 | } | 5062 | } |
5051 | 5063 | ||
5052 | void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) | ||
5053 | { | ||
5054 | struct desc_ptr dt = { limit, base }; | ||
5055 | |||
5056 | kvm_x86_ops->set_gdt(vcpu, &dt); | ||
5057 | } | ||
5058 | |||
5059 | void realmode_lidt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) | ||
5060 | { | ||
5061 | struct desc_ptr dt = { limit, base }; | ||
5062 | |||
5063 | kvm_x86_ops->set_idt(vcpu, &dt); | ||
5064 | } | ||
5065 | |||
5066 | static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i) | 5064 | static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i) |
5067 | { | 5065 | { |
5068 | struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i]; | 5066 | struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i]; |