diff options
author | Ingo Molnar <mingo@elte.hu> | 2007-01-05 19:36:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2007-01-06 02:55:21 -0500 |
commit | 965b58a550b6f84815cb555e6abb953e863f1610 (patch) | |
tree | bb21eb8c919f78662d422528126cffdbe1352983 /drivers | |
parent | cd36beec0b83d28dceb85696a23542bf1b97cc8c (diff) |
[PATCH] KVM: Fix GFP_KERNEL alloc in atomic section bug
KVM does kmalloc() in an atomic section while having preemption disabled via
vcpu_load(). Fix this by moving the ->*_msr setup from the vcpu_setup method
to the vcpu_create method.
(This is also a small speedup for setting up a vcpu, which can in theory be
more frequent than the vcpu_create method).
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/kvm/vmx.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index d0a2c2d5342a..fbab07af6574 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c | |||
@@ -1094,14 +1094,6 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) | |||
1094 | rdmsrl(MSR_IA32_SYSENTER_EIP, a); | 1094 | rdmsrl(MSR_IA32_SYSENTER_EIP, a); |
1095 | vmcs_writel(HOST_IA32_SYSENTER_EIP, a); /* 22.2.3 */ | 1095 | vmcs_writel(HOST_IA32_SYSENTER_EIP, a); /* 22.2.3 */ |
1096 | 1096 | ||
1097 | ret = -ENOMEM; | ||
1098 | vcpu->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
1099 | if (!vcpu->guest_msrs) | ||
1100 | goto out; | ||
1101 | vcpu->host_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
1102 | if (!vcpu->host_msrs) | ||
1103 | goto out_free_guest_msrs; | ||
1104 | |||
1105 | for (i = 0; i < NR_VMX_MSR; ++i) { | 1097 | for (i = 0; i < NR_VMX_MSR; ++i) { |
1106 | u32 index = vmx_msr_index[i]; | 1098 | u32 index = vmx_msr_index[i]; |
1107 | u32 data_low, data_high; | 1099 | u32 data_low, data_high; |
@@ -1155,8 +1147,6 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) | |||
1155 | 1147 | ||
1156 | return 0; | 1148 | return 0; |
1157 | 1149 | ||
1158 | out_free_guest_msrs: | ||
1159 | kfree(vcpu->guest_msrs); | ||
1160 | out: | 1150 | out: |
1161 | return ret; | 1151 | return ret; |
1162 | } | 1152 | } |
@@ -1906,13 +1896,33 @@ static int vmx_create_vcpu(struct kvm_vcpu *vcpu) | |||
1906 | { | 1896 | { |
1907 | struct vmcs *vmcs; | 1897 | struct vmcs *vmcs; |
1908 | 1898 | ||
1899 | vcpu->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
1900 | if (!vcpu->guest_msrs) | ||
1901 | return -ENOMEM; | ||
1902 | |||
1903 | vcpu->host_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
1904 | if (!vcpu->host_msrs) | ||
1905 | goto out_free_guest_msrs; | ||
1906 | |||
1909 | vmcs = alloc_vmcs(); | 1907 | vmcs = alloc_vmcs(); |
1910 | if (!vmcs) | 1908 | if (!vmcs) |
1911 | return -ENOMEM; | 1909 | goto out_free_msrs; |
1910 | |||
1912 | vmcs_clear(vmcs); | 1911 | vmcs_clear(vmcs); |
1913 | vcpu->vmcs = vmcs; | 1912 | vcpu->vmcs = vmcs; |
1914 | vcpu->launched = 0; | 1913 | vcpu->launched = 0; |
1914 | |||
1915 | return 0; | 1915 | return 0; |
1916 | |||
1917 | out_free_msrs: | ||
1918 | kfree(vcpu->host_msrs); | ||
1919 | vcpu->host_msrs = NULL; | ||
1920 | |||
1921 | out_free_guest_msrs: | ||
1922 | kfree(vcpu->guest_msrs); | ||
1923 | vcpu->guest_msrs = NULL; | ||
1924 | |||
1925 | return -ENOMEM; | ||
1916 | } | 1926 | } |
1917 | 1927 | ||
1918 | static struct kvm_arch_ops vmx_arch_ops = { | 1928 | static struct kvm_arch_ops vmx_arch_ops = { |