aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/kvm/kvm.h1
-rw-r--r--drivers/kvm/kvm_main.c64
-rw-r--r--drivers/kvm/svm.c5
-rw-r--r--drivers/kvm/vmx.c8
4 files changed, 77 insertions, 1 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index c48cebf8511d..04574a9d4430 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -341,6 +341,7 @@ struct kvm_arch_ops {
341 341
342 struct kvm_vcpu *(*vcpu_load)(struct kvm_vcpu *vcpu); 342 struct kvm_vcpu *(*vcpu_load)(struct kvm_vcpu *vcpu);
343 void (*vcpu_put)(struct kvm_vcpu *vcpu); 343 void (*vcpu_put)(struct kvm_vcpu *vcpu);
344 void (*vcpu_decache)(struct kvm_vcpu *vcpu);
344 345
345 int (*set_guest_debug)(struct kvm_vcpu *vcpu, 346 int (*set_guest_debug)(struct kvm_vcpu *vcpu,
346 struct kvm_debug_guest *dbg); 347 struct kvm_debug_guest *dbg);
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index a6cd1c1fe29a..291d298868fc 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -34,6 +34,7 @@
34#include <linux/highmem.h> 34#include <linux/highmem.h>
35#include <linux/file.h> 35#include <linux/file.h>
36#include <asm/desc.h> 36#include <asm/desc.h>
37#include <linux/cpu.h>
37 38
38#include "x86_emulate.h" 39#include "x86_emulate.h"
39#include "segment_descriptor.h" 40#include "segment_descriptor.h"
@@ -2039,6 +2040,64 @@ static struct notifier_block kvm_reboot_notifier = {
2039 .priority = 0, 2040 .priority = 0,
2040}; 2041};
2041 2042
2043/*
2044 * Make sure that a cpu that is being hot-unplugged does not have any vcpus
2045 * cached on it.
2046 */
2047static void decache_vcpus_on_cpu(int cpu)
2048{
2049 struct kvm *vm;
2050 struct kvm_vcpu *vcpu;
2051 int i;
2052
2053 spin_lock(&kvm_lock);
2054 list_for_each_entry(vm, &vm_list, vm_list)
2055 for (i = 0; i < KVM_MAX_VCPUS; ++i) {
2056 vcpu = &vm->vcpus[i];
2057 /*
2058 * If the vcpu is locked, then it is running on some
2059 * other cpu and therefore it is not cached on the
2060 * cpu in question.
2061 *
2062 * If it's not locked, check the last cpu it executed
2063 * on.
2064 */
2065 if (mutex_trylock(&vcpu->mutex)) {
2066 if (vcpu->cpu == cpu) {
2067 kvm_arch_ops->vcpu_decache(vcpu);
2068 vcpu->cpu = -1;
2069 }
2070 mutex_unlock(&vcpu->mutex);
2071 }
2072 }
2073 spin_unlock(&kvm_lock);
2074}
2075
2076static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
2077 void *v)
2078{
2079 int cpu = (long)v;
2080
2081 switch (val) {
2082 case CPU_DEAD:
2083 case CPU_UP_CANCELED:
2084 decache_vcpus_on_cpu(cpu);
2085 smp_call_function_single(cpu, kvm_arch_ops->hardware_disable,
2086 NULL, 0, 1);
2087 break;
2088 case CPU_UP_PREPARE:
2089 smp_call_function_single(cpu, kvm_arch_ops->hardware_enable,
2090 NULL, 0, 1);
2091 break;
2092 }
2093 return NOTIFY_OK;
2094}
2095
2096static struct notifier_block kvm_cpu_notifier = {
2097 .notifier_call = kvm_cpu_hotplug,
2098 .priority = 20, /* must be > scheduler priority */
2099};
2100
2042static __init void kvm_init_debug(void) 2101static __init void kvm_init_debug(void)
2043{ 2102{
2044 struct kvm_stats_debugfs_item *p; 2103 struct kvm_stats_debugfs_item *p;
@@ -2085,6 +2144,9 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module)
2085 return r; 2144 return r;
2086 2145
2087 on_each_cpu(kvm_arch_ops->hardware_enable, NULL, 0, 1); 2146 on_each_cpu(kvm_arch_ops->hardware_enable, NULL, 0, 1);
2147 r = register_cpu_notifier(&kvm_cpu_notifier);
2148 if (r)
2149 goto out_free_1;
2088 register_reboot_notifier(&kvm_reboot_notifier); 2150 register_reboot_notifier(&kvm_reboot_notifier);
2089 2151
2090 kvm_chardev_ops.owner = module; 2152 kvm_chardev_ops.owner = module;
@@ -2099,6 +2161,8 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module)
2099 2161
2100out_free: 2162out_free:
2101 unregister_reboot_notifier(&kvm_reboot_notifier); 2163 unregister_reboot_notifier(&kvm_reboot_notifier);
2164 unregister_cpu_notifier(&kvm_cpu_notifier);
2165out_free_1:
2102 on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1); 2166 on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1);
2103 kvm_arch_ops->hardware_unsetup(); 2167 kvm_arch_ops->hardware_unsetup();
2104 return r; 2168 return r;
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 4fa50bd0dceb..83da4ea150a3 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -609,6 +609,10 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu)
609 put_cpu(); 609 put_cpu();
610} 610}
611 611
612static void svm_vcpu_decache(struct kvm_vcpu *vcpu)
613{
614}
615
612static void svm_cache_regs(struct kvm_vcpu *vcpu) 616static void svm_cache_regs(struct kvm_vcpu *vcpu)
613{ 617{
614 vcpu->regs[VCPU_REGS_RAX] = vcpu->svm->vmcb->save.rax; 618 vcpu->regs[VCPU_REGS_RAX] = vcpu->svm->vmcb->save.rax;
@@ -1677,6 +1681,7 @@ static struct kvm_arch_ops svm_arch_ops = {
1677 1681
1678 .vcpu_load = svm_vcpu_load, 1682 .vcpu_load = svm_vcpu_load,
1679 .vcpu_put = svm_vcpu_put, 1683 .vcpu_put = svm_vcpu_put,
1684 .vcpu_decache = svm_vcpu_decache,
1680 1685
1681 .set_guest_debug = svm_guest_debug, 1686 .set_guest_debug = svm_guest_debug,
1682 .get_msr = svm_get_msr, 1687 .get_msr = svm_get_msr,
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 28da0cae64a7..1e640b899175 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -250,6 +250,11 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
250 put_cpu(); 250 put_cpu();
251} 251}
252 252
253static void vmx_vcpu_decache(struct kvm_vcpu *vcpu)
254{
255 vcpu_clear(vcpu);
256}
257
253static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu) 258static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
254{ 259{
255 return vmcs_readl(GUEST_RFLAGS); 260 return vmcs_readl(GUEST_RFLAGS);
@@ -509,7 +514,7 @@ static __init int vmx_disabled_by_bios(void)
509 return (msr & 5) == 1; /* locked but not enabled */ 514 return (msr & 5) == 1; /* locked but not enabled */
510} 515}
511 516
512static __init void hardware_enable(void *garbage) 517static void hardware_enable(void *garbage)
513{ 518{
514 int cpu = raw_smp_processor_id(); 519 int cpu = raw_smp_processor_id();
515 u64 phys_addr = __pa(per_cpu(vmxarea, cpu)); 520 u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
@@ -2023,6 +2028,7 @@ static struct kvm_arch_ops vmx_arch_ops = {
2023 2028
2024 .vcpu_load = vmx_vcpu_load, 2029 .vcpu_load = vmx_vcpu_load,
2025 .vcpu_put = vmx_vcpu_put, 2030 .vcpu_put = vmx_vcpu_put,
2031 .vcpu_decache = vmx_vcpu_decache,
2026 2032
2027 .set_guest_debug = set_guest_debug, 2033 .set_guest_debug = set_guest_debug,
2028 .get_msr = vmx_get_msr, 2034 .get_msr = vmx_get_msr,