diff options
author | Gleb Natapov <gleb@redhat.com> | 2010-04-13 03:05:23 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-05-17 05:17:39 -0400 |
commit | 020df0794f5764e742feaa718be88b8f1b4ce04f (patch) | |
tree | ce0fca4af2beba046c8632e663bfc082681c6afa /arch/x86/kvm/x86.c | |
parent | 6bc31bdc55cad6609b1610b4cecad312664f2808 (diff) |
KVM: move DR register access handling into generic code
Currently both SVM and VMX have their own DR handling code. Move it to
x86.c.
Acked-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r-- | arch/x86/kvm/x86.c | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index d65e481c5fa4..09dccac2df7e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -562,6 +562,80 @@ unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu) | |||
562 | } | 562 | } |
563 | EXPORT_SYMBOL_GPL(kvm_get_cr8); | 563 | EXPORT_SYMBOL_GPL(kvm_get_cr8); |
564 | 564 | ||
565 | int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) | ||
566 | { | ||
567 | switch (dr) { | ||
568 | case 0 ... 3: | ||
569 | vcpu->arch.db[dr] = val; | ||
570 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) | ||
571 | vcpu->arch.eff_db[dr] = val; | ||
572 | break; | ||
573 | case 4: | ||
574 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { | ||
575 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
576 | return 1; | ||
577 | } | ||
578 | /* fall through */ | ||
579 | case 6: | ||
580 | if (val & 0xffffffff00000000ULL) { | ||
581 | kvm_inject_gp(vcpu, 0); | ||
582 | return 1; | ||
583 | } | ||
584 | vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1; | ||
585 | break; | ||
586 | case 5: | ||
587 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { | ||
588 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
589 | return 1; | ||
590 | } | ||
591 | /* fall through */ | ||
592 | default: /* 7 */ | ||
593 | if (val & 0xffffffff00000000ULL) { | ||
594 | kvm_inject_gp(vcpu, 0); | ||
595 | return 1; | ||
596 | } | ||
597 | vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1; | ||
598 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { | ||
599 | kvm_x86_ops->set_dr7(vcpu, vcpu->arch.dr7); | ||
600 | vcpu->arch.switch_db_regs = (val & DR7_BP_EN_MASK); | ||
601 | } | ||
602 | break; | ||
603 | } | ||
604 | |||
605 | return 0; | ||
606 | } | ||
607 | EXPORT_SYMBOL_GPL(kvm_set_dr); | ||
608 | |||
609 | int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) | ||
610 | { | ||
611 | switch (dr) { | ||
612 | case 0 ... 3: | ||
613 | *val = vcpu->arch.db[dr]; | ||
614 | break; | ||
615 | case 4: | ||
616 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { | ||
617 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
618 | return 1; | ||
619 | } | ||
620 | /* fall through */ | ||
621 | case 6: | ||
622 | *val = vcpu->arch.dr6; | ||
623 | break; | ||
624 | case 5: | ||
625 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { | ||
626 | kvm_queue_exception(vcpu, UD_VECTOR); | ||
627 | return 1; | ||
628 | } | ||
629 | /* fall through */ | ||
630 | default: /* 7 */ | ||
631 | *val = vcpu->arch.dr7; | ||
632 | break; | ||
633 | } | ||
634 | |||
635 | return 0; | ||
636 | } | ||
637 | EXPORT_SYMBOL_GPL(kvm_get_dr); | ||
638 | |||
565 | static inline u32 bit(int bitno) | 639 | static inline u32 bit(int bitno) |
566 | { | 640 | { |
567 | return 1 << (bitno & 31); | 641 | return 1 << (bitno & 31); |
@@ -3483,14 +3557,14 @@ int emulate_clts(struct kvm_vcpu *vcpu) | |||
3483 | 3557 | ||
3484 | int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) | 3558 | int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest) |
3485 | { | 3559 | { |
3486 | return kvm_x86_ops->get_dr(ctxt->vcpu, dr, dest); | 3560 | return kvm_get_dr(ctxt->vcpu, dr, dest); |
3487 | } | 3561 | } |
3488 | 3562 | ||
3489 | int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) | 3563 | int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value) |
3490 | { | 3564 | { |
3491 | unsigned long mask = (ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U; | 3565 | unsigned long mask = (ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U; |
3492 | 3566 | ||
3493 | return kvm_x86_ops->set_dr(ctxt->vcpu, dr, value & mask); | 3567 | return kvm_set_dr(ctxt->vcpu, dr, value & mask); |
3494 | } | 3568 | } |
3495 | 3569 | ||
3496 | void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) | 3570 | void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) |