aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2010-04-28 12:15:32 -0400
committerAvi Kivity <avi@redhat.com>2010-08-01 03:35:32 -0400
commit338dbc9781eb5acd0b12809d95d4006135f29767 (patch)
treeceb9fc9b2eb7e52c9352f094436590c82852d71f /arch
parent0f12244fe70e8a94a491f6cd7ed70a352ab6c26c (diff)
KVM: x86 emulator: make (get|set)_dr() callback return error if it fails
Make (get|set)_dr() callback return error if it fails instead of injecting exception behind emulator's back. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/emulate.c11
-rw-r--r--arch/x86/kvm/x86.c63
2 files changed, 45 insertions, 29 deletions
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 061f7d37c9f7..d5979ecc2521 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -3151,9 +3151,14 @@ twobyte_insn:
3151 goto done; 3151 goto done;
3152 } 3152 }
3153 3153
3154 ops->set_dr(c->modrm_reg,c->regs[c->modrm_rm] & 3154 if (ops->set_dr(c->modrm_reg, c->regs[c->modrm_rm] &
3155 ((ctxt->mode == X86EMUL_MODE_PROT64) ? ~0ULL : ~0U), 3155 ((ctxt->mode == X86EMUL_MODE_PROT64) ?
3156 ctxt->vcpu); 3156 ~0ULL : ~0U), ctxt->vcpu) < 0) {
3157 /* #UD condition is already handled by the code above */
3158 kvm_inject_gp(ctxt->vcpu, 0);
3159 goto done;
3160 }
3161
3157 c->dst.type = OP_NONE; /* no writeback */ 3162 c->dst.type = OP_NONE; /* no writeback */
3158 break; 3163 break;
3159 case 0x30: 3164 case 0x30:
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 64c6e7a31411..44a546b136fc 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -573,7 +573,7 @@ unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu)
573} 573}
574EXPORT_SYMBOL_GPL(kvm_get_cr8); 574EXPORT_SYMBOL_GPL(kvm_get_cr8);
575 575
576int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val) 576static int __kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val)
577{ 577{
578 switch (dr) { 578 switch (dr) {
579 case 0 ... 3: 579 case 0 ... 3:
@@ -582,29 +582,21 @@ int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val)
582 vcpu->arch.eff_db[dr] = val; 582 vcpu->arch.eff_db[dr] = val;
583 break; 583 break;
584 case 4: 584 case 4:
585 if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { 585 if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
586 kvm_queue_exception(vcpu, UD_VECTOR); 586 return 1; /* #UD */
587 return 1;
588 }
589 /* fall through */ 587 /* fall through */
590 case 6: 588 case 6:
591 if (val & 0xffffffff00000000ULL) { 589 if (val & 0xffffffff00000000ULL)
592 kvm_inject_gp(vcpu, 0); 590 return -1; /* #GP */
593 return 1;
594 }
595 vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1; 591 vcpu->arch.dr6 = (val & DR6_VOLATILE) | DR6_FIXED_1;
596 break; 592 break;
597 case 5: 593 case 5:
598 if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { 594 if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
599 kvm_queue_exception(vcpu, UD_VECTOR); 595 return 1; /* #UD */
600 return 1;
601 }
602 /* fall through */ 596 /* fall through */
603 default: /* 7 */ 597 default: /* 7 */
604 if (val & 0xffffffff00000000ULL) { 598 if (val & 0xffffffff00000000ULL)
605 kvm_inject_gp(vcpu, 0); 599 return -1; /* #GP */
606 return 1;
607 }
608 vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1; 600 vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1;
609 if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { 601 if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
610 kvm_x86_ops->set_dr7(vcpu, vcpu->arch.dr7); 602 kvm_x86_ops->set_dr7(vcpu, vcpu->arch.dr7);
@@ -615,28 +607,37 @@ int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val)
615 607
616 return 0; 608 return 0;
617} 609}
610
611int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val)
612{
613 int res;
614
615 res = __kvm_set_dr(vcpu, dr, val);
616 if (res > 0)
617 kvm_queue_exception(vcpu, UD_VECTOR);
618 else if (res < 0)
619 kvm_inject_gp(vcpu, 0);
620
621 return res;
622}
618EXPORT_SYMBOL_GPL(kvm_set_dr); 623EXPORT_SYMBOL_GPL(kvm_set_dr);
619 624
620int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val) 625static int _kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val)
621{ 626{
622 switch (dr) { 627 switch (dr) {
623 case 0 ... 3: 628 case 0 ... 3:
624 *val = vcpu->arch.db[dr]; 629 *val = vcpu->arch.db[dr];
625 break; 630 break;
626 case 4: 631 case 4:
627 if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { 632 if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
628 kvm_queue_exception(vcpu, UD_VECTOR);
629 return 1; 633 return 1;
630 }
631 /* fall through */ 634 /* fall through */
632 case 6: 635 case 6:
633 *val = vcpu->arch.dr6; 636 *val = vcpu->arch.dr6;
634 break; 637 break;
635 case 5: 638 case 5:
636 if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) { 639 if (kvm_read_cr4_bits(vcpu, X86_CR4_DE))
637 kvm_queue_exception(vcpu, UD_VECTOR);
638 return 1; 640 return 1;
639 }
640 /* fall through */ 641 /* fall through */
641 default: /* 7 */ 642 default: /* 7 */
642 *val = vcpu->arch.dr7; 643 *val = vcpu->arch.dr7;
@@ -645,6 +646,15 @@ int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val)
645 646
646 return 0; 647 return 0;
647} 648}
649
650int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val)
651{
652 if (_kvm_get_dr(vcpu, dr, val)) {
653 kvm_queue_exception(vcpu, UD_VECTOR);
654 return 1;
655 }
656 return 0;
657}
648EXPORT_SYMBOL_GPL(kvm_get_dr); 658EXPORT_SYMBOL_GPL(kvm_get_dr);
649 659
650static inline u32 bit(int bitno) 660static inline u32 bit(int bitno)
@@ -3619,12 +3629,13 @@ int emulate_clts(struct kvm_vcpu *vcpu)
3619 3629
3620int emulator_get_dr(int dr, unsigned long *dest, struct kvm_vcpu *vcpu) 3630int emulator_get_dr(int dr, unsigned long *dest, struct kvm_vcpu *vcpu)
3621{ 3631{
3622 return kvm_get_dr(vcpu, dr, dest); 3632 return _kvm_get_dr(vcpu, dr, dest);
3623} 3633}
3624 3634
3625int emulator_set_dr(int dr, unsigned long value, struct kvm_vcpu *vcpu) 3635int emulator_set_dr(int dr, unsigned long value, struct kvm_vcpu *vcpu)
3626{ 3636{
3627 return kvm_set_dr(vcpu, dr, value); 3637
3638 return __kvm_set_dr(vcpu, dr, value);
3628} 3639}
3629 3640
3630void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) 3641void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context)