diff options
author | Avi Kivity <avi@qumranet.com> | 2007-05-02 10:57:40 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-07-16 05:05:39 -0400 |
commit | abd3f2d622a810b7f6687f7ddb405e90e4cfb7ab (patch) | |
tree | 12ae80f61aee8e6ca709db2bf08ed0ab54c431e6 /drivers/kvm/vmx.c | |
parent | 707c08743060b6721b08df68f4fd546b106e7510 (diff) |
KVM: Rationalize exception bitmap usage
Everyone owns a piece of the exception bitmap, but they happily write to
the entire thing like there's no tomorrow. Centralize handling in
update_exception_bitmap() and have everyone call that.
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/vmx.c')
-rw-r--r-- | drivers/kvm/vmx.c | 42 |
1 files changed, 21 insertions, 21 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index 93c3abfc1e0a..2190020e055b 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c | |||
@@ -237,6 +237,20 @@ static void vmcs_set_bits(unsigned long field, u32 mask) | |||
237 | vmcs_writel(field, vmcs_readl(field) | mask); | 237 | vmcs_writel(field, vmcs_readl(field) | mask); |
238 | } | 238 | } |
239 | 239 | ||
240 | static void update_exception_bitmap(struct kvm_vcpu *vcpu) | ||
241 | { | ||
242 | u32 eb; | ||
243 | |||
244 | eb = 1u << PF_VECTOR; | ||
245 | if (!vcpu->fpu_active) | ||
246 | eb |= 1u << NM_VECTOR; | ||
247 | if (vcpu->guest_debug.enabled) | ||
248 | eb |= 1u << 1; | ||
249 | if (vcpu->rmode.active) | ||
250 | eb = ~0; | ||
251 | vmcs_write32(EXCEPTION_BITMAP, eb); | ||
252 | } | ||
253 | |||
240 | static void reload_tss(void) | 254 | static void reload_tss(void) |
241 | { | 255 | { |
242 | #ifndef CONFIG_X86_64 | 256 | #ifndef CONFIG_X86_64 |
@@ -618,10 +632,8 @@ static void vcpu_put_rsp_rip(struct kvm_vcpu *vcpu) | |||
618 | static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) | 632 | static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) |
619 | { | 633 | { |
620 | unsigned long dr7 = 0x400; | 634 | unsigned long dr7 = 0x400; |
621 | u32 exception_bitmap; | ||
622 | int old_singlestep; | 635 | int old_singlestep; |
623 | 636 | ||
624 | exception_bitmap = vmcs_read32(EXCEPTION_BITMAP); | ||
625 | old_singlestep = vcpu->guest_debug.singlestep; | 637 | old_singlestep = vcpu->guest_debug.singlestep; |
626 | 638 | ||
627 | vcpu->guest_debug.enabled = dbg->enabled; | 639 | vcpu->guest_debug.enabled = dbg->enabled; |
@@ -637,13 +649,9 @@ static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) | |||
637 | dr7 |= 0 << (i*4+16); /* execution breakpoint */ | 649 | dr7 |= 0 << (i*4+16); /* execution breakpoint */ |
638 | } | 650 | } |
639 | 651 | ||
640 | exception_bitmap |= (1u << 1); /* Trap debug exceptions */ | ||
641 | |||
642 | vcpu->guest_debug.singlestep = dbg->singlestep; | 652 | vcpu->guest_debug.singlestep = dbg->singlestep; |
643 | } else { | 653 | } else |
644 | exception_bitmap &= ~(1u << 1); /* Ignore debug exceptions */ | ||
645 | vcpu->guest_debug.singlestep = 0; | 654 | vcpu->guest_debug.singlestep = 0; |
646 | } | ||
647 | 655 | ||
648 | if (old_singlestep && !vcpu->guest_debug.singlestep) { | 656 | if (old_singlestep && !vcpu->guest_debug.singlestep) { |
649 | unsigned long flags; | 657 | unsigned long flags; |
@@ -653,7 +661,7 @@ static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) | |||
653 | vmcs_writel(GUEST_RFLAGS, flags); | 661 | vmcs_writel(GUEST_RFLAGS, flags); |
654 | } | 662 | } |
655 | 663 | ||
656 | vmcs_write32(EXCEPTION_BITMAP, exception_bitmap); | 664 | update_exception_bitmap(vcpu); |
657 | vmcs_writel(GUEST_DR7, dr7); | 665 | vmcs_writel(GUEST_DR7, dr7); |
658 | 666 | ||
659 | return 0; | 667 | return 0; |
@@ -767,14 +775,6 @@ static __exit void hardware_unsetup(void) | |||
767 | free_kvm_area(); | 775 | free_kvm_area(); |
768 | } | 776 | } |
769 | 777 | ||
770 | static void update_exception_bitmap(struct kvm_vcpu *vcpu) | ||
771 | { | ||
772 | if (vcpu->rmode.active) | ||
773 | vmcs_write32(EXCEPTION_BITMAP, ~0); | ||
774 | else | ||
775 | vmcs_write32(EXCEPTION_BITMAP, 1 << PF_VECTOR); | ||
776 | } | ||
777 | |||
778 | static void fix_pmode_dataseg(int seg, struct kvm_save_segment *save) | 778 | static void fix_pmode_dataseg(int seg, struct kvm_save_segment *save) |
779 | { | 779 | { |
780 | struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; | 780 | struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; |
@@ -942,7 +942,7 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | |||
942 | 942 | ||
943 | if (!(cr0 & CR0_TS_MASK)) { | 943 | if (!(cr0 & CR0_TS_MASK)) { |
944 | vcpu->fpu_active = 1; | 944 | vcpu->fpu_active = 1; |
945 | vmcs_clear_bits(EXCEPTION_BITMAP, CR0_TS_MASK); | 945 | update_exception_bitmap(vcpu); |
946 | } | 946 | } |
947 | 947 | ||
948 | vmcs_writel(CR0_READ_SHADOW, cr0); | 948 | vmcs_writel(CR0_READ_SHADOW, cr0); |
@@ -958,7 +958,7 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) | |||
958 | if (!(vcpu->cr0 & CR0_TS_MASK)) { | 958 | if (!(vcpu->cr0 & CR0_TS_MASK)) { |
959 | vcpu->fpu_active = 0; | 959 | vcpu->fpu_active = 0; |
960 | vmcs_set_bits(GUEST_CR0, CR0_TS_MASK); | 960 | vmcs_set_bits(GUEST_CR0, CR0_TS_MASK); |
961 | vmcs_set_bits(EXCEPTION_BITMAP, 1 << NM_VECTOR); | 961 | update_exception_bitmap(vcpu); |
962 | } | 962 | } |
963 | } | 963 | } |
964 | 964 | ||
@@ -1243,7 +1243,6 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) | |||
1243 | | CPU_BASED_USE_TSC_OFFSETING /* 21.3 */ | 1243 | | CPU_BASED_USE_TSC_OFFSETING /* 21.3 */ |
1244 | ); | 1244 | ); |
1245 | 1245 | ||
1246 | vmcs_write32(EXCEPTION_BITMAP, 1 << PF_VECTOR); | ||
1247 | vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, 0); | 1246 | vmcs_write32(PAGE_FAULT_ERROR_CODE_MASK, 0); |
1248 | vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, 0); | 1247 | vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, 0); |
1249 | vmcs_write32(CR3_TARGET_COUNT, 0); /* 22.2.1 */ | 1248 | vmcs_write32(CR3_TARGET_COUNT, 0); /* 22.2.1 */ |
@@ -1329,6 +1328,7 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) | |||
1329 | #ifdef CONFIG_X86_64 | 1328 | #ifdef CONFIG_X86_64 |
1330 | vmx_set_efer(vcpu, 0); | 1329 | vmx_set_efer(vcpu, 0); |
1331 | #endif | 1330 | #endif |
1331 | update_exception_bitmap(vcpu); | ||
1332 | 1332 | ||
1333 | return 0; | 1333 | return 0; |
1334 | 1334 | ||
@@ -1489,7 +1489,7 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
1489 | 1489 | ||
1490 | if (is_no_device(intr_info)) { | 1490 | if (is_no_device(intr_info)) { |
1491 | vcpu->fpu_active = 1; | 1491 | vcpu->fpu_active = 1; |
1492 | vmcs_clear_bits(EXCEPTION_BITMAP, 1 << NM_VECTOR); | 1492 | update_exception_bitmap(vcpu); |
1493 | if (!(vcpu->cr0 & CR0_TS_MASK)) | 1493 | if (!(vcpu->cr0 & CR0_TS_MASK)) |
1494 | vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK); | 1494 | vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK); |
1495 | return 1; | 1495 | return 1; |
@@ -1684,7 +1684,7 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
1684 | case 2: /* clts */ | 1684 | case 2: /* clts */ |
1685 | vcpu_load_rsp_rip(vcpu); | 1685 | vcpu_load_rsp_rip(vcpu); |
1686 | vcpu->fpu_active = 1; | 1686 | vcpu->fpu_active = 1; |
1687 | vmcs_clear_bits(EXCEPTION_BITMAP, 1 << NM_VECTOR); | 1687 | update_exception_bitmap(vcpu); |
1688 | vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK); | 1688 | vmcs_clear_bits(GUEST_CR0, CR0_TS_MASK); |
1689 | vcpu->cr0 &= ~CR0_TS_MASK; | 1689 | vcpu->cr0 &= ~CR0_TS_MASK; |
1690 | vmcs_writel(CR0_READ_SHADOW, vcpu->cr0); | 1690 | vmcs_writel(CR0_READ_SHADOW, vcpu->cr0); |