aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-05-02 10:57:40 -0400
committerAvi Kivity <avi@qumranet.com>2007-07-16 05:05:39 -0400
commitabd3f2d622a810b7f6687f7ddb405e90e4cfb7ab (patch)
tree12ae80f61aee8e6ca709db2bf08ed0ab54c431e6
parent707c08743060b6721b08df68f4fd546b106e7510 (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>
-rw-r--r--drivers/kvm/vmx.c42
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
240static 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
240static void reload_tss(void) 254static 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)
618static int set_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg) 632static 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
770static 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
778static void fix_pmode_dataseg(int seg, struct kvm_save_segment *save) 778static 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);