aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-03-18 09:20:03 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:15:54 -0400
commit52a4661737ecc918633f6b05c611a4af4b5eae5a (patch)
tree25bf976f23423db921b5edde6854f0dc8391eb1c /arch/x86
parent6ce5a090a9a0ea4266a2cad058c69e2f27201e11 (diff)
KVM: Provide callback to get/set control registers in emulator ops.
Use this callback instead of directly call kvm function. Also rename realmode_(set|get)_cr to emulator_(set|get)_cr since function has nothing to do with real mode. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/kvm_emulate.h3
-rw-r--r--arch/x86/include/asm/kvm_host.h2
-rw-r--r--arch/x86/kvm/emulate.c7
-rw-r--r--arch/x86/kvm/x86.c114
4 files changed, 63 insertions, 63 deletions
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 2666d7ac3229..0c5caa469eb8 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -108,7 +108,8 @@ struct x86_emulate_ops {
108 const void *new, 108 const void *new,
109 unsigned int bytes, 109 unsigned int bytes,
110 struct kvm_vcpu *vcpu); 110 struct kvm_vcpu *vcpu);
111 111 ulong (*get_cr)(int cr, struct kvm_vcpu *vcpu);
112 void (*set_cr)(int cr, ulong val, struct kvm_vcpu *vcpu);
112}; 113};
113 114
114/* Type, address-of, and value of an instruction's operand. */ 115/* Type, address-of, and value of an instruction's operand. */
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 53f520259471..9d474c7ae261 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -586,8 +586,6 @@ void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
586void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, 586void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw,
587 unsigned long *rflags); 587 unsigned long *rflags);
588 588
589unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr);
590void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long value);
591void kvm_enable_efer_bits(u64); 589void kvm_enable_efer_bits(u64);
592int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *data); 590int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *data);
593int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); 591int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 91450b5cd49e..5b060e4be0e3 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2483,7 +2483,7 @@ twobyte_insn:
2483 break; 2483 break;
2484 case 4: /* smsw */ 2484 case 4: /* smsw */
2485 c->dst.bytes = 2; 2485 c->dst.bytes = 2;
2486 c->dst.val = realmode_get_cr(ctxt->vcpu, 0); 2486 c->dst.val = ops->get_cr(0, ctxt->vcpu);
2487 break; 2487 break;
2488 case 6: /* lmsw */ 2488 case 6: /* lmsw */
2489 realmode_lmsw(ctxt->vcpu, (u16)c->src.val, 2489 realmode_lmsw(ctxt->vcpu, (u16)c->src.val,
@@ -2519,8 +2519,7 @@ twobyte_insn:
2519 case 0x20: /* mov cr, reg */ 2519 case 0x20: /* mov cr, reg */
2520 if (c->modrm_mod != 3) 2520 if (c->modrm_mod != 3)
2521 goto cannot_emulate; 2521 goto cannot_emulate;
2522 c->regs[c->modrm_rm] = 2522 c->regs[c->modrm_rm] = ops->get_cr(c->modrm_reg, ctxt->vcpu);
2523 realmode_get_cr(ctxt->vcpu, c->modrm_reg);
2524 c->dst.type = OP_NONE; /* no writeback */ 2523 c->dst.type = OP_NONE; /* no writeback */
2525 break; 2524 break;
2526 case 0x21: /* mov from dr to reg */ 2525 case 0x21: /* mov from dr to reg */
@@ -2534,7 +2533,7 @@ twobyte_insn:
2534 case 0x22: /* mov reg, cr */ 2533 case 0x22: /* mov reg, cr */
2535 if (c->modrm_mod != 3) 2534 if (c->modrm_mod != 3)
2536 goto cannot_emulate; 2535 goto cannot_emulate;
2537 realmode_set_cr(ctxt->vcpu, c->modrm_reg, c->modrm_val); 2536 ops->set_cr(c->modrm_reg, c->modrm_val, ctxt->vcpu);
2538 c->dst.type = OP_NONE; 2537 c->dst.type = OP_NONE;
2539 break; 2538 break;
2540 case 0x23: /* mov from reg to dr */ 2539 case 0x23: /* mov from reg to dr */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 35db4f0db4ea..94a29759ab2c 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3423,12 +3423,70 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)
3423} 3423}
3424EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); 3424EXPORT_SYMBOL_GPL(kvm_report_emulation_failure);
3425 3425
3426static u64 mk_cr_64(u64 curr_cr, u32 new_val)
3427{
3428 return (curr_cr & ~((1ULL << 32) - 1)) | new_val;
3429}
3430
3431static unsigned long emulator_get_cr(int cr, struct kvm_vcpu *vcpu)
3432{
3433 unsigned long value;
3434
3435 switch (cr) {
3436 case 0:
3437 value = kvm_read_cr0(vcpu);
3438 break;
3439 case 2:
3440 value = vcpu->arch.cr2;
3441 break;
3442 case 3:
3443 value = vcpu->arch.cr3;
3444 break;
3445 case 4:
3446 value = kvm_read_cr4(vcpu);
3447 break;
3448 case 8:
3449 value = kvm_get_cr8(vcpu);
3450 break;
3451 default:
3452 vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr);
3453 return 0;
3454 }
3455
3456 return value;
3457}
3458
3459static void emulator_set_cr(int cr, unsigned long val, struct kvm_vcpu *vcpu)
3460{
3461 switch (cr) {
3462 case 0:
3463 kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val));
3464 break;
3465 case 2:
3466 vcpu->arch.cr2 = val;
3467 break;
3468 case 3:
3469 kvm_set_cr3(vcpu, val);
3470 break;
3471 case 4:
3472 kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val));
3473 break;
3474 case 8:
3475 kvm_set_cr8(vcpu, val & 0xfUL);
3476 break;
3477 default:
3478 vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr);
3479 }
3480}
3481
3426static struct x86_emulate_ops emulate_ops = { 3482static struct x86_emulate_ops emulate_ops = {
3427 .read_std = kvm_read_guest_virt_system, 3483 .read_std = kvm_read_guest_virt_system,
3428 .fetch = kvm_fetch_guest_virt, 3484 .fetch = kvm_fetch_guest_virt,
3429 .read_emulated = emulator_read_emulated, 3485 .read_emulated = emulator_read_emulated,
3430 .write_emulated = emulator_write_emulated, 3486 .write_emulated = emulator_write_emulated,
3431 .cmpxchg_emulated = emulator_cmpxchg_emulated, 3487 .cmpxchg_emulated = emulator_cmpxchg_emulated,
3488 .get_cr = emulator_get_cr,
3489 .set_cr = emulator_set_cr,
3432}; 3490};
3433 3491
3434static void cache_all_regs(struct kvm_vcpu *vcpu) 3492static void cache_all_regs(struct kvm_vcpu *vcpu)
@@ -4026,11 +4084,6 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
4026 return __emulator_write_emulated(rip, instruction, 3, vcpu, false); 4084 return __emulator_write_emulated(rip, instruction, 3, vcpu, false);
4027} 4085}
4028 4086
4029static u64 mk_cr_64(u64 curr_cr, u32 new_val)
4030{
4031 return (curr_cr & ~((1ULL << 32) - 1)) | new_val;
4032}
4033
4034void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base) 4087void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base)
4035{ 4088{
4036 struct desc_ptr dt = { limit, base }; 4089 struct desc_ptr dt = { limit, base };
@@ -4052,57 +4105,6 @@ void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw,
4052 *rflags = kvm_get_rflags(vcpu); 4105 *rflags = kvm_get_rflags(vcpu);
4053} 4106}
4054 4107
4055unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr)
4056{
4057 unsigned long value;
4058
4059 switch (cr) {
4060 case 0:
4061 value = kvm_read_cr0(vcpu);
4062 break;
4063 case 2:
4064 value = vcpu->arch.cr2;
4065 break;
4066 case 3:
4067 value = vcpu->arch.cr3;
4068 break;
4069 case 4:
4070 value = kvm_read_cr4(vcpu);
4071 break;
4072 case 8:
4073 value = kvm_get_cr8(vcpu);
4074 break;
4075 default:
4076 vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr);
4077 return 0;
4078 }
4079
4080 return value;
4081}
4082
4083void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val)
4084{
4085 switch (cr) {
4086 case 0:
4087 kvm_set_cr0(vcpu, mk_cr_64(kvm_read_cr0(vcpu), val));
4088 break;
4089 case 2:
4090 vcpu->arch.cr2 = val;
4091 break;
4092 case 3:
4093 kvm_set_cr3(vcpu, val);
4094 break;
4095 case 4:
4096 kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val));
4097 break;
4098 case 8:
4099 kvm_set_cr8(vcpu, val & 0xfUL);
4100 break;
4101 default:
4102 vcpu_printf(vcpu, "%s: unexpected cr %u\n", __func__, cr);
4103 }
4104}
4105
4106static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i) 4108static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i)
4107{ 4109{
4108 struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i]; 4110 struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i];