diff options
| -rw-r--r-- | arch/x86/kvm/vmx.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index b2a913bb07e0..a9940ec9e215 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -43,6 +43,7 @@ | |||
| 43 | #include <asm/i387.h> | 43 | #include <asm/i387.h> |
| 44 | #include <asm/xcr.h> | 44 | #include <asm/xcr.h> |
| 45 | #include <asm/perf_event.h> | 45 | #include <asm/perf_event.h> |
| 46 | #include <asm/debugreg.h> | ||
| 46 | #include <asm/kexec.h> | 47 | #include <asm/kexec.h> |
| 47 | 48 | ||
| 48 | #include "trace.h" | 49 | #include "trace.h" |
| @@ -2850,7 +2851,7 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
| 2850 | vmx_capability.ept, vmx_capability.vpid); | 2851 | vmx_capability.ept, vmx_capability.vpid); |
| 2851 | } | 2852 | } |
| 2852 | 2853 | ||
| 2853 | min = 0; | 2854 | min = VM_EXIT_SAVE_DEBUG_CONTROLS; |
| 2854 | #ifdef CONFIG_X86_64 | 2855 | #ifdef CONFIG_X86_64 |
| 2855 | min |= VM_EXIT_HOST_ADDR_SPACE_SIZE; | 2856 | min |= VM_EXIT_HOST_ADDR_SPACE_SIZE; |
| 2856 | #endif | 2857 | #endif |
| @@ -5084,6 +5085,22 @@ static int handle_dr(struct kvm_vcpu *vcpu) | |||
| 5084 | } | 5085 | } |
| 5085 | } | 5086 | } |
| 5086 | 5087 | ||
| 5088 | if (vcpu->guest_debug == 0) { | ||
| 5089 | u32 cpu_based_vm_exec_control; | ||
| 5090 | |||
| 5091 | cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); | ||
| 5092 | cpu_based_vm_exec_control &= ~CPU_BASED_MOV_DR_EXITING; | ||
| 5093 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); | ||
| 5094 | |||
| 5095 | /* | ||
| 5096 | * No more DR vmexits; force a reload of the debug registers | ||
| 5097 | * and reenter on this instruction. The next vmexit will | ||
| 5098 | * retrieve the full state of the debug registers. | ||
| 5099 | */ | ||
| 5100 | vcpu->arch.switch_db_regs |= KVM_DEBUGREG_WONT_EXIT; | ||
| 5101 | return 1; | ||
| 5102 | } | ||
| 5103 | |||
| 5087 | exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | 5104 | exit_qualification = vmcs_readl(EXIT_QUALIFICATION); |
| 5088 | dr = exit_qualification & DEBUG_REG_ACCESS_NUM; | 5105 | dr = exit_qualification & DEBUG_REG_ACCESS_NUM; |
| 5089 | reg = DEBUG_REG_ACCESS_REG(exit_qualification); | 5106 | reg = DEBUG_REG_ACCESS_REG(exit_qualification); |
| @@ -5110,6 +5127,24 @@ static void vmx_set_dr6(struct kvm_vcpu *vcpu, unsigned long val) | |||
| 5110 | { | 5127 | { |
| 5111 | } | 5128 | } |
| 5112 | 5129 | ||
| 5130 | static void vmx_sync_dirty_debug_regs(struct kvm_vcpu *vcpu) | ||
| 5131 | { | ||
| 5132 | u32 cpu_based_vm_exec_control; | ||
| 5133 | |||
| 5134 | get_debugreg(vcpu->arch.db[0], 0); | ||
| 5135 | get_debugreg(vcpu->arch.db[1], 1); | ||
| 5136 | get_debugreg(vcpu->arch.db[2], 2); | ||
| 5137 | get_debugreg(vcpu->arch.db[3], 3); | ||
| 5138 | get_debugreg(vcpu->arch.dr6, 6); | ||
| 5139 | vcpu->arch.dr7 = vmcs_readl(GUEST_DR7); | ||
| 5140 | |||
| 5141 | vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_WONT_EXIT; | ||
| 5142 | |||
| 5143 | cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); | ||
| 5144 | cpu_based_vm_exec_control |= CPU_BASED_MOV_DR_EXITING; | ||
| 5145 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); | ||
| 5146 | } | ||
| 5147 | |||
| 5113 | static void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val) | 5148 | static void vmx_set_dr7(struct kvm_vcpu *vcpu, unsigned long val) |
| 5114 | { | 5149 | { |
| 5115 | vmcs_writel(GUEST_DR7, val); | 5150 | vmcs_writel(GUEST_DR7, val); |
| @@ -8628,6 +8663,7 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
| 8628 | .get_dr6 = vmx_get_dr6, | 8663 | .get_dr6 = vmx_get_dr6, |
| 8629 | .set_dr6 = vmx_set_dr6, | 8664 | .set_dr6 = vmx_set_dr6, |
| 8630 | .set_dr7 = vmx_set_dr7, | 8665 | .set_dr7 = vmx_set_dr7, |
| 8666 | .sync_dirty_debug_regs = vmx_sync_dirty_debug_regs, | ||
| 8631 | .cache_reg = vmx_cache_reg, | 8667 | .cache_reg = vmx_cache_reg, |
| 8632 | .get_rflags = vmx_get_rflags, | 8668 | .get_rflags = vmx_get_rflags, |
| 8633 | .set_rflags = vmx_set_rflags, | 8669 | .set_rflags = vmx_set_rflags, |
