diff options
author | Avi Kivity <avi@qumranet.com> | 2007-11-20 08:30:24 -0500 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:53:09 -0500 |
commit | 26e5215fdc6cf7b5a8b1269134095abbb7338b3c (patch) | |
tree | d5a326a910996549827a11beb3af1c60f1f1cf3c | |
parent | 0de10343b3ca7aa34dd606145748f73ed19f627e (diff) |
KVM: Split vcpu creation to avoid vcpu_load() before preemption setup
Split kvm_arch_vcpu_create() into kvm_arch_vcpu_create() and
kvm_arch_vcpu_setup(), enabling preemption notification between the two.
This mean that we can now do vcpu_load() within kvm_arch_vcpu_setup().
Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r-- | drivers/kvm/kvm.h | 1 | ||||
-rw-r--r-- | drivers/kvm/kvm_main.c | 4 | ||||
-rw-r--r-- | drivers/kvm/x86.c | 16 |
3 files changed, 12 insertions, 9 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index 49094a221f6a..b65f5dee4b1b 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h | |||
@@ -466,6 +466,7 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu); | |||
466 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu); | 466 | void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu); |
467 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu); | 467 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu); |
468 | struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id); | 468 | struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id); |
469 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu); | ||
469 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu); | 470 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu); |
470 | 471 | ||
471 | int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu); | 472 | int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu); |
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 9dd6ad3c6c7b..7939b5c9a4b4 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -769,6 +769,10 @@ static int kvm_vm_ioctl_create_vcpu(struct kvm *kvm, int n) | |||
769 | 769 | ||
770 | preempt_notifier_init(&vcpu->preempt_notifier, &kvm_preempt_ops); | 770 | preempt_notifier_init(&vcpu->preempt_notifier, &kvm_preempt_ops); |
771 | 771 | ||
772 | r = kvm_arch_vcpu_setup(vcpu); | ||
773 | if (r) | ||
774 | goto vcpu_destroy; | ||
775 | |||
772 | mutex_lock(&kvm->lock); | 776 | mutex_lock(&kvm->lock); |
773 | if (kvm->vcpus[n]) { | 777 | if (kvm->vcpus[n]) { |
774 | r = -EEXIST; | 778 | r = -EEXIST; |
diff --git a/drivers/kvm/x86.c b/drivers/kvm/x86.c index 6abb2ed1a908..b482b6a8a828 100644 --- a/drivers/kvm/x86.c +++ b/drivers/kvm/x86.c | |||
@@ -2478,13 +2478,12 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu) | |||
2478 | struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | 2478 | struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, |
2479 | unsigned int id) | 2479 | unsigned int id) |
2480 | { | 2480 | { |
2481 | int r; | 2481 | return kvm_x86_ops->vcpu_create(kvm, id); |
2482 | struct kvm_vcpu *vcpu = kvm_x86_ops->vcpu_create(kvm, id); | 2482 | } |
2483 | 2483 | ||
2484 | if (IS_ERR(vcpu)) { | 2484 | int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) |
2485 | r = -ENOMEM; | 2485 | { |
2486 | goto fail; | 2486 | int r; |
2487 | } | ||
2488 | 2487 | ||
2489 | /* We do fxsave: this must be aligned. */ | 2488 | /* We do fxsave: this must be aligned. */ |
2490 | BUG_ON((unsigned long)&vcpu->host_fx_image & 0xF); | 2489 | BUG_ON((unsigned long)&vcpu->host_fx_image & 0xF); |
@@ -2497,11 +2496,10 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, | |||
2497 | if (r < 0) | 2496 | if (r < 0) |
2498 | goto free_vcpu; | 2497 | goto free_vcpu; |
2499 | 2498 | ||
2500 | return vcpu; | 2499 | return 0; |
2501 | free_vcpu: | 2500 | free_vcpu: |
2502 | kvm_x86_ops->vcpu_free(vcpu); | 2501 | kvm_x86_ops->vcpu_free(vcpu); |
2503 | fail: | 2502 | return r; |
2504 | return ERR_PTR(r); | ||
2505 | } | 2503 | } |
2506 | 2504 | ||
2507 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) | 2505 | void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) |