diff options
Diffstat (limited to 'drivers/kvm/vmx.c')
-rw-r--r-- | drivers/kvm/vmx.c | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index 27e05a77e21a..1e640b899175 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c | |||
@@ -125,6 +125,15 @@ static void __vcpu_clear(void *arg) | |||
125 | per_cpu(current_vmcs, cpu) = NULL; | 125 | per_cpu(current_vmcs, cpu) = NULL; |
126 | } | 126 | } |
127 | 127 | ||
128 | static void vcpu_clear(struct kvm_vcpu *vcpu) | ||
129 | { | ||
130 | if (vcpu->cpu != raw_smp_processor_id() && vcpu->cpu != -1) | ||
131 | smp_call_function_single(vcpu->cpu, __vcpu_clear, vcpu, 0, 1); | ||
132 | else | ||
133 | __vcpu_clear(vcpu); | ||
134 | vcpu->launched = 0; | ||
135 | } | ||
136 | |||
128 | static unsigned long vmcs_readl(unsigned long field) | 137 | static unsigned long vmcs_readl(unsigned long field) |
129 | { | 138 | { |
130 | unsigned long value; | 139 | unsigned long value; |
@@ -202,10 +211,8 @@ static struct kvm_vcpu *vmx_vcpu_load(struct kvm_vcpu *vcpu) | |||
202 | 211 | ||
203 | cpu = get_cpu(); | 212 | cpu = get_cpu(); |
204 | 213 | ||
205 | if (vcpu->cpu != cpu) { | 214 | if (vcpu->cpu != cpu) |
206 | smp_call_function(__vcpu_clear, vcpu, 0, 1); | 215 | vcpu_clear(vcpu); |
207 | vcpu->launched = 0; | ||
208 | } | ||
209 | 216 | ||
210 | if (per_cpu(current_vmcs, cpu) != vcpu->vmcs) { | 217 | if (per_cpu(current_vmcs, cpu) != vcpu->vmcs) { |
211 | u8 error; | 218 | u8 error; |
@@ -243,6 +250,11 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu) | |||
243 | put_cpu(); | 250 | put_cpu(); |
244 | } | 251 | } |
245 | 252 | ||
253 | static void vmx_vcpu_decache(struct kvm_vcpu *vcpu) | ||
254 | { | ||
255 | vcpu_clear(vcpu); | ||
256 | } | ||
257 | |||
246 | static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) | 258 | static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) |
247 | { | 259 | { |
248 | return vmcs_readl(GUEST_RFLAGS); | 260 | return vmcs_readl(GUEST_RFLAGS); |
@@ -502,7 +514,7 @@ static __init int vmx_disabled_by_bios(void) | |||
502 | return (msr & 5) == 1; /* locked but not enabled */ | 514 | return (msr & 5) == 1; /* locked but not enabled */ |
503 | } | 515 | } |
504 | 516 | ||
505 | static __init void hardware_enable(void *garbage) | 517 | static void hardware_enable(void *garbage) |
506 | { | 518 | { |
507 | int cpu = raw_smp_processor_id(); | 519 | int cpu = raw_smp_processor_id(); |
508 | u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); | 520 | u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); |
@@ -1375,6 +1387,11 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu, | |||
1375 | return 1; | 1387 | return 1; |
1376 | } | 1388 | } |
1377 | 1389 | ||
1390 | static int handle_triple_fault(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
1391 | { | ||
1392 | kvm_run->exit_reason = KVM_EXIT_SHUTDOWN; | ||
1393 | return 0; | ||
1394 | } | ||
1378 | 1395 | ||
1379 | static int get_io_count(struct kvm_vcpu *vcpu, u64 *count) | 1396 | static int get_io_count(struct kvm_vcpu *vcpu, u64 *count) |
1380 | { | 1397 | { |
@@ -1635,6 +1652,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu, | |||
1635 | struct kvm_run *kvm_run) = { | 1652 | struct kvm_run *kvm_run) = { |
1636 | [EXIT_REASON_EXCEPTION_NMI] = handle_exception, | 1653 | [EXIT_REASON_EXCEPTION_NMI] = handle_exception, |
1637 | [EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt, | 1654 | [EXIT_REASON_EXTERNAL_INTERRUPT] = handle_external_interrupt, |
1655 | [EXIT_REASON_TRIPLE_FAULT] = handle_triple_fault, | ||
1638 | [EXIT_REASON_IO_INSTRUCTION] = handle_io, | 1656 | [EXIT_REASON_IO_INSTRUCTION] = handle_io, |
1639 | [EXIT_REASON_CR_ACCESS] = handle_cr, | 1657 | [EXIT_REASON_CR_ACCESS] = handle_cr, |
1640 | [EXIT_REASON_DR_ACCESS] = handle_dr, | 1658 | [EXIT_REASON_DR_ACCESS] = handle_dr, |
@@ -1786,10 +1804,10 @@ again: | |||
1786 | "kvm_vmx_return: " | 1804 | "kvm_vmx_return: " |
1787 | /* Save guest registers, load host registers, keep flags */ | 1805 | /* Save guest registers, load host registers, keep flags */ |
1788 | #ifdef CONFIG_X86_64 | 1806 | #ifdef CONFIG_X86_64 |
1789 | "xchg %3, 0(%%rsp) \n\t" | 1807 | "xchg %3, (%%rsp) \n\t" |
1790 | "mov %%rax, %c[rax](%3) \n\t" | 1808 | "mov %%rax, %c[rax](%3) \n\t" |
1791 | "mov %%rbx, %c[rbx](%3) \n\t" | 1809 | "mov %%rbx, %c[rbx](%3) \n\t" |
1792 | "pushq 0(%%rsp); popq %c[rcx](%3) \n\t" | 1810 | "pushq (%%rsp); popq %c[rcx](%3) \n\t" |
1793 | "mov %%rdx, %c[rdx](%3) \n\t" | 1811 | "mov %%rdx, %c[rdx](%3) \n\t" |
1794 | "mov %%rsi, %c[rsi](%3) \n\t" | 1812 | "mov %%rsi, %c[rsi](%3) \n\t" |
1795 | "mov %%rdi, %c[rdi](%3) \n\t" | 1813 | "mov %%rdi, %c[rdi](%3) \n\t" |
@@ -1804,24 +1822,24 @@ again: | |||
1804 | "mov %%r15, %c[r15](%3) \n\t" | 1822 | "mov %%r15, %c[r15](%3) \n\t" |
1805 | "mov %%cr2, %%rax \n\t" | 1823 | "mov %%cr2, %%rax \n\t" |
1806 | "mov %%rax, %c[cr2](%3) \n\t" | 1824 | "mov %%rax, %c[cr2](%3) \n\t" |
1807 | "mov 0(%%rsp), %3 \n\t" | 1825 | "mov (%%rsp), %3 \n\t" |
1808 | 1826 | ||
1809 | "pop %%rcx; pop %%r15; pop %%r14; pop %%r13; pop %%r12;" | 1827 | "pop %%rcx; pop %%r15; pop %%r14; pop %%r13; pop %%r12;" |
1810 | "pop %%r11; pop %%r10; pop %%r9; pop %%r8;" | 1828 | "pop %%r11; pop %%r10; pop %%r9; pop %%r8;" |
1811 | "pop %%rbp; pop %%rdi; pop %%rsi;" | 1829 | "pop %%rbp; pop %%rdi; pop %%rsi;" |
1812 | "pop %%rdx; pop %%rbx; pop %%rax \n\t" | 1830 | "pop %%rdx; pop %%rbx; pop %%rax \n\t" |
1813 | #else | 1831 | #else |
1814 | "xchg %3, 0(%%esp) \n\t" | 1832 | "xchg %3, (%%esp) \n\t" |
1815 | "mov %%eax, %c[rax](%3) \n\t" | 1833 | "mov %%eax, %c[rax](%3) \n\t" |
1816 | "mov %%ebx, %c[rbx](%3) \n\t" | 1834 | "mov %%ebx, %c[rbx](%3) \n\t" |
1817 | "pushl 0(%%esp); popl %c[rcx](%3) \n\t" | 1835 | "pushl (%%esp); popl %c[rcx](%3) \n\t" |
1818 | "mov %%edx, %c[rdx](%3) \n\t" | 1836 | "mov %%edx, %c[rdx](%3) \n\t" |
1819 | "mov %%esi, %c[rsi](%3) \n\t" | 1837 | "mov %%esi, %c[rsi](%3) \n\t" |
1820 | "mov %%edi, %c[rdi](%3) \n\t" | 1838 | "mov %%edi, %c[rdi](%3) \n\t" |
1821 | "mov %%ebp, %c[rbp](%3) \n\t" | 1839 | "mov %%ebp, %c[rbp](%3) \n\t" |
1822 | "mov %%cr2, %%eax \n\t" | 1840 | "mov %%cr2, %%eax \n\t" |
1823 | "mov %%eax, %c[cr2](%3) \n\t" | 1841 | "mov %%eax, %c[cr2](%3) \n\t" |
1824 | "mov 0(%%esp), %3 \n\t" | 1842 | "mov (%%esp), %3 \n\t" |
1825 | 1843 | ||
1826 | "pop %%ecx; popa \n\t" | 1844 | "pop %%ecx; popa \n\t" |
1827 | #endif | 1845 | #endif |
@@ -1859,9 +1877,7 @@ again: | |||
1859 | fx_restore(vcpu->host_fx_image); | 1877 | fx_restore(vcpu->host_fx_image); |
1860 | vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0; | 1878 | vcpu->interrupt_window_open = (vmcs_read32(GUEST_INTERRUPTIBILITY_INFO) & 3) == 0; |
1861 | 1879 | ||
1862 | #ifndef CONFIG_X86_64 | ||
1863 | asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); | 1880 | asm ("mov %0, %%ds; mov %0, %%es" : : "r"(__USER_DS)); |
1864 | #endif | ||
1865 | 1881 | ||
1866 | /* | 1882 | /* |
1867 | * Profile KVM exit RIPs: | 1883 | * Profile KVM exit RIPs: |
@@ -2012,6 +2028,7 @@ static struct kvm_arch_ops vmx_arch_ops = { | |||
2012 | 2028 | ||
2013 | .vcpu_load = vmx_vcpu_load, | 2029 | .vcpu_load = vmx_vcpu_load, |
2014 | .vcpu_put = vmx_vcpu_put, | 2030 | .vcpu_put = vmx_vcpu_put, |
2031 | .vcpu_decache = vmx_vcpu_decache, | ||
2015 | 2032 | ||
2016 | .set_guest_debug = set_guest_debug, | 2033 | .set_guest_debug = set_guest_debug, |
2017 | .get_msr = vmx_get_msr, | 2034 | .get_msr = vmx_get_msr, |