Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 48044
b: refs/heads/master
c: 774c47f
h: refs/heads/master
v: v3
  • Loading branch information
Avi Kivity authored and Linus Torvalds committed Feb 12, 2007
1 parent 37bbdad commit 5afa597
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 8d0be2b3bf4a55606967d7d84e56c52521e94333
refs/heads/master: 774c47f1d78e373a6bd2964f4e278d1ce26c21cb
1 change: 1 addition & 0 deletions trunk/drivers/kvm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ struct kvm_arch_ops {

struct kvm_vcpu *(*vcpu_load)(struct kvm_vcpu *vcpu);
void (*vcpu_put)(struct kvm_vcpu *vcpu);
void (*vcpu_decache)(struct kvm_vcpu *vcpu);

int (*set_guest_debug)(struct kvm_vcpu *vcpu,
struct kvm_debug_guest *dbg);
Expand Down
64 changes: 64 additions & 0 deletions trunk/drivers/kvm/kvm_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <linux/highmem.h>
#include <linux/file.h>
#include <asm/desc.h>
#include <linux/cpu.h>

#include "x86_emulate.h"
#include "segment_descriptor.h"
Expand Down Expand Up @@ -2039,6 +2040,64 @@ static struct notifier_block kvm_reboot_notifier = {
.priority = 0,
};

/*
* Make sure that a cpu that is being hot-unplugged does not have any vcpus
* cached on it.
*/
static void decache_vcpus_on_cpu(int cpu)
{
struct kvm *vm;
struct kvm_vcpu *vcpu;
int i;

spin_lock(&kvm_lock);
list_for_each_entry(vm, &vm_list, vm_list)
for (i = 0; i < KVM_MAX_VCPUS; ++i) {
vcpu = &vm->vcpus[i];
/*
* If the vcpu is locked, then it is running on some
* other cpu and therefore it is not cached on the
* cpu in question.
*
* If it's not locked, check the last cpu it executed
* on.
*/
if (mutex_trylock(&vcpu->mutex)) {
if (vcpu->cpu == cpu) {
kvm_arch_ops->vcpu_decache(vcpu);
vcpu->cpu = -1;
}
mutex_unlock(&vcpu->mutex);
}
}
spin_unlock(&kvm_lock);
}

static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val,
void *v)
{
int cpu = (long)v;

switch (val) {
case CPU_DEAD:
case CPU_UP_CANCELED:
decache_vcpus_on_cpu(cpu);
smp_call_function_single(cpu, kvm_arch_ops->hardware_disable,
NULL, 0, 1);
break;
case CPU_UP_PREPARE:
smp_call_function_single(cpu, kvm_arch_ops->hardware_enable,
NULL, 0, 1);
break;
}
return NOTIFY_OK;
}

static struct notifier_block kvm_cpu_notifier = {
.notifier_call = kvm_cpu_hotplug,
.priority = 20, /* must be > scheduler priority */
};

static __init void kvm_init_debug(void)
{
struct kvm_stats_debugfs_item *p;
Expand Down Expand Up @@ -2085,6 +2144,9 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module)
return r;

on_each_cpu(kvm_arch_ops->hardware_enable, NULL, 0, 1);
r = register_cpu_notifier(&kvm_cpu_notifier);
if (r)
goto out_free_1;
register_reboot_notifier(&kvm_reboot_notifier);

kvm_chardev_ops.owner = module;
Expand All @@ -2099,6 +2161,8 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module)

out_free:
unregister_reboot_notifier(&kvm_reboot_notifier);
unregister_cpu_notifier(&kvm_cpu_notifier);
out_free_1:
on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1);
kvm_arch_ops->hardware_unsetup();
return r;
Expand Down
5 changes: 5 additions & 0 deletions trunk/drivers/kvm/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,10 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu)
put_cpu();
}

static void svm_vcpu_decache(struct kvm_vcpu *vcpu)
{
}

static void svm_cache_regs(struct kvm_vcpu *vcpu)
{
vcpu->regs[VCPU_REGS_RAX] = vcpu->svm->vmcb->save.rax;
Expand Down Expand Up @@ -1677,6 +1681,7 @@ static struct kvm_arch_ops svm_arch_ops = {

.vcpu_load = svm_vcpu_load,
.vcpu_put = svm_vcpu_put,
.vcpu_decache = svm_vcpu_decache,

.set_guest_debug = svm_guest_debug,
.get_msr = svm_get_msr,
Expand Down
8 changes: 7 additions & 1 deletion trunk/drivers/kvm/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,11 @@ static void vmx_vcpu_put(struct kvm_vcpu *vcpu)
put_cpu();
}

static void vmx_vcpu_decache(struct kvm_vcpu *vcpu)
{
vcpu_clear(vcpu);
}

static unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
{
return vmcs_readl(GUEST_RFLAGS);
Expand Down Expand Up @@ -509,7 +514,7 @@ static __init int vmx_disabled_by_bios(void)
return (msr & 5) == 1; /* locked but not enabled */
}

static __init void hardware_enable(void *garbage)
static void hardware_enable(void *garbage)
{
int cpu = raw_smp_processor_id();
u64 phys_addr = __pa(per_cpu(vmxarea, cpu));
Expand Down Expand Up @@ -2023,6 +2028,7 @@ static struct kvm_arch_ops vmx_arch_ops = {

.vcpu_load = vmx_vcpu_load,
.vcpu_put = vmx_vcpu_put,
.vcpu_decache = vmx_vcpu_decache,

.set_guest_debug = set_guest_debug,
.get_msr = vmx_get_msr,
Expand Down

0 comments on commit 5afa597

Please sign in to comment.