Skip to content

Commit 34a1cd6

Browse files
TiejunChenbonzini
authored andcommitted
kvm: x86: vmx: move some vmx setting from vmx_init() to hardware_setup()
Instead of vmx_init(), actually it would make reasonable sense to do anything specific to vmx hardware setting in vmx_x86_ops->hardware_setup(). Signed-off-by: Tiejun Chen <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent f2c7648 commit 34a1cd6

File tree

1 file changed

+133
-134
lines changed

1 file changed

+133
-134
lines changed

arch/x86/kvm/vmx.c

Lines changed: 133 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -5720,8 +5720,108 @@ static void update_ple_window_actual_max(void)
57205720

57215721
static __init int hardware_setup(void)
57225722
{
5723-
if (setup_vmcs_config(&vmcs_config) < 0)
5724-
return -EIO;
5723+
int r = -ENOMEM, i, msr;
5724+
5725+
rdmsrl_safe(MSR_EFER, &host_efer);
5726+
5727+
for (i = 0; i < ARRAY_SIZE(vmx_msr_index); ++i)
5728+
kvm_define_shared_msr(i, vmx_msr_index[i]);
5729+
5730+
vmx_io_bitmap_a = (unsigned long *)__get_free_page(GFP_KERNEL);
5731+
if (!vmx_io_bitmap_a)
5732+
return r;
5733+
5734+
vmx_io_bitmap_b = (unsigned long *)__get_free_page(GFP_KERNEL);
5735+
if (!vmx_io_bitmap_b)
5736+
goto out;
5737+
5738+
vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page(GFP_KERNEL);
5739+
if (!vmx_msr_bitmap_legacy)
5740+
goto out1;
5741+
5742+
vmx_msr_bitmap_legacy_x2apic =
5743+
(unsigned long *)__get_free_page(GFP_KERNEL);
5744+
if (!vmx_msr_bitmap_legacy_x2apic)
5745+
goto out2;
5746+
5747+
vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL);
5748+
if (!vmx_msr_bitmap_longmode)
5749+
goto out3;
5750+
5751+
vmx_msr_bitmap_longmode_x2apic =
5752+
(unsigned long *)__get_free_page(GFP_KERNEL);
5753+
if (!vmx_msr_bitmap_longmode_x2apic)
5754+
goto out4;
5755+
vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
5756+
if (!vmx_vmread_bitmap)
5757+
goto out5;
5758+
5759+
vmx_vmwrite_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
5760+
if (!vmx_vmwrite_bitmap)
5761+
goto out6;
5762+
5763+
memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
5764+
memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
5765+
5766+
/*
5767+
* Allow direct access to the PC debug port (it is often used for I/O
5768+
* delays, but the vmexits simply slow things down).
5769+
*/
5770+
memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE);
5771+
clear_bit(0x80, vmx_io_bitmap_a);
5772+
5773+
memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE);
5774+
5775+
memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
5776+
memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);
5777+
5778+
vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
5779+
vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
5780+
vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
5781+
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
5782+
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
5783+
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
5784+
vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);
5785+
5786+
memcpy(vmx_msr_bitmap_legacy_x2apic,
5787+
vmx_msr_bitmap_legacy, PAGE_SIZE);
5788+
memcpy(vmx_msr_bitmap_longmode_x2apic,
5789+
vmx_msr_bitmap_longmode, PAGE_SIZE);
5790+
5791+
if (enable_apicv) {
5792+
for (msr = 0x800; msr <= 0x8ff; msr++)
5793+
vmx_disable_intercept_msr_read_x2apic(msr);
5794+
5795+
/* According SDM, in x2apic mode, the whole id reg is used.
5796+
* But in KVM, it only use the highest eight bits. Need to
5797+
* intercept it */
5798+
vmx_enable_intercept_msr_read_x2apic(0x802);
5799+
/* TMCCT */
5800+
vmx_enable_intercept_msr_read_x2apic(0x839);
5801+
/* TPR */
5802+
vmx_disable_intercept_msr_write_x2apic(0x808);
5803+
/* EOI */
5804+
vmx_disable_intercept_msr_write_x2apic(0x80b);
5805+
/* SELF-IPI */
5806+
vmx_disable_intercept_msr_write_x2apic(0x83f);
5807+
}
5808+
5809+
if (enable_ept) {
5810+
kvm_mmu_set_mask_ptes(0ull,
5811+
(enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
5812+
(enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull,
5813+
0ull, VMX_EPT_EXECUTABLE_MASK);
5814+
ept_set_mmio_spte_mask();
5815+
kvm_enable_tdp();
5816+
} else
5817+
kvm_disable_tdp();
5818+
5819+
update_ple_window_actual_max();
5820+
5821+
if (setup_vmcs_config(&vmcs_config) < 0) {
5822+
r = -EIO;
5823+
goto out7;
5824+
}
57255825

57265826
if (boot_cpu_has(X86_FEATURE_NX))
57275827
kvm_enable_efer_bits(EFER_NX);
@@ -5781,10 +5881,38 @@ static __init int hardware_setup(void)
57815881
nested_vmx_setup_ctls_msrs();
57825882

57835883
return alloc_kvm_area();
5884+
5885+
out7:
5886+
free_page((unsigned long)vmx_vmwrite_bitmap);
5887+
out6:
5888+
free_page((unsigned long)vmx_vmread_bitmap);
5889+
out5:
5890+
free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic);
5891+
out4:
5892+
free_page((unsigned long)vmx_msr_bitmap_longmode);
5893+
out3:
5894+
free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic);
5895+
out2:
5896+
free_page((unsigned long)vmx_msr_bitmap_legacy);
5897+
out1:
5898+
free_page((unsigned long)vmx_io_bitmap_b);
5899+
out:
5900+
free_page((unsigned long)vmx_io_bitmap_a);
5901+
5902+
return r;
57845903
}
57855904

57865905
static __exit void hardware_unsetup(void)
57875906
{
5907+
free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic);
5908+
free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic);
5909+
free_page((unsigned long)vmx_msr_bitmap_legacy);
5910+
free_page((unsigned long)vmx_msr_bitmap_longmode);
5911+
free_page((unsigned long)vmx_io_bitmap_b);
5912+
free_page((unsigned long)vmx_io_bitmap_a);
5913+
free_page((unsigned long)vmx_vmwrite_bitmap);
5914+
free_page((unsigned long)vmx_vmread_bitmap);
5915+
57885916
free_kvm_area();
57895917
}
57905918

@@ -9187,150 +9315,21 @@ static struct kvm_x86_ops vmx_x86_ops = {
91879315

91889316
static int __init vmx_init(void)
91899317
{
9190-
int r, i, msr;
9191-
9192-
rdmsrl_safe(MSR_EFER, &host_efer);
9193-
9194-
for (i = 0; i < ARRAY_SIZE(vmx_msr_index); ++i)
9195-
kvm_define_shared_msr(i, vmx_msr_index[i]);
9196-
9197-
vmx_io_bitmap_a = (unsigned long *)__get_free_page(GFP_KERNEL);
9198-
if (!vmx_io_bitmap_a)
9199-
return -ENOMEM;
9200-
9201-
r = -ENOMEM;
9202-
9203-
vmx_io_bitmap_b = (unsigned long *)__get_free_page(GFP_KERNEL);
9204-
if (!vmx_io_bitmap_b)
9205-
goto out;
9206-
9207-
vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page(GFP_KERNEL);
9208-
if (!vmx_msr_bitmap_legacy)
9209-
goto out1;
9210-
9211-
vmx_msr_bitmap_legacy_x2apic =
9212-
(unsigned long *)__get_free_page(GFP_KERNEL);
9213-
if (!vmx_msr_bitmap_legacy_x2apic)
9214-
goto out2;
9215-
9216-
vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL);
9217-
if (!vmx_msr_bitmap_longmode)
9218-
goto out3;
9219-
9220-
vmx_msr_bitmap_longmode_x2apic =
9221-
(unsigned long *)__get_free_page(GFP_KERNEL);
9222-
if (!vmx_msr_bitmap_longmode_x2apic)
9223-
goto out4;
9224-
vmx_vmread_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
9225-
if (!vmx_vmread_bitmap)
9226-
goto out5;
9227-
9228-
vmx_vmwrite_bitmap = (unsigned long *)__get_free_page(GFP_KERNEL);
9229-
if (!vmx_vmwrite_bitmap)
9230-
goto out6;
9231-
9232-
memset(vmx_vmread_bitmap, 0xff, PAGE_SIZE);
9233-
memset(vmx_vmwrite_bitmap, 0xff, PAGE_SIZE);
9234-
9235-
/*
9236-
* Allow direct access to the PC debug port (it is often used for I/O
9237-
* delays, but the vmexits simply slow things down).
9238-
*/
9239-
memset(vmx_io_bitmap_a, 0xff, PAGE_SIZE);
9240-
clear_bit(0x80, vmx_io_bitmap_a);
9241-
9242-
memset(vmx_io_bitmap_b, 0xff, PAGE_SIZE);
9243-
9244-
memset(vmx_msr_bitmap_legacy, 0xff, PAGE_SIZE);
9245-
memset(vmx_msr_bitmap_longmode, 0xff, PAGE_SIZE);
9246-
9247-
set_bit(0, vmx_vpid_bitmap); /* 0 is reserved for host */
9248-
9249-
r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx),
9250-
__alignof__(struct vcpu_vmx), THIS_MODULE);
9318+
int r = kvm_init(&vmx_x86_ops, sizeof(struct vcpu_vmx),
9319+
__alignof__(struct vcpu_vmx), THIS_MODULE);
92519320
if (r)
9252-
goto out7;
9321+
return r;
92539322

92549323
#ifdef CONFIG_KEXEC
92559324
rcu_assign_pointer(crash_vmclear_loaded_vmcss,
92569325
crash_vmclear_local_loaded_vmcss);
92579326
#endif
92589327

9259-
vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
9260-
vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
9261-
vmx_disable_intercept_for_msr(MSR_KERNEL_GS_BASE, true);
9262-
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false);
9263-
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false);
9264-
vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false);
9265-
vmx_disable_intercept_for_msr(MSR_IA32_BNDCFGS, true);
9266-
9267-
memcpy(vmx_msr_bitmap_legacy_x2apic,
9268-
vmx_msr_bitmap_legacy, PAGE_SIZE);
9269-
memcpy(vmx_msr_bitmap_longmode_x2apic,
9270-
vmx_msr_bitmap_longmode, PAGE_SIZE);
9271-
9272-
if (enable_apicv) {
9273-
for (msr = 0x800; msr <= 0x8ff; msr++)
9274-
vmx_disable_intercept_msr_read_x2apic(msr);
9275-
9276-
/* According SDM, in x2apic mode, the whole id reg is used.
9277-
* But in KVM, it only use the highest eight bits. Need to
9278-
* intercept it */
9279-
vmx_enable_intercept_msr_read_x2apic(0x802);
9280-
/* TMCCT */
9281-
vmx_enable_intercept_msr_read_x2apic(0x839);
9282-
/* TPR */
9283-
vmx_disable_intercept_msr_write_x2apic(0x808);
9284-
/* EOI */
9285-
vmx_disable_intercept_msr_write_x2apic(0x80b);
9286-
/* SELF-IPI */
9287-
vmx_disable_intercept_msr_write_x2apic(0x83f);
9288-
}
9289-
9290-
if (enable_ept) {
9291-
kvm_mmu_set_mask_ptes(0ull,
9292-
(enable_ept_ad_bits) ? VMX_EPT_ACCESS_BIT : 0ull,
9293-
(enable_ept_ad_bits) ? VMX_EPT_DIRTY_BIT : 0ull,
9294-
0ull, VMX_EPT_EXECUTABLE_MASK);
9295-
ept_set_mmio_spte_mask();
9296-
kvm_enable_tdp();
9297-
} else
9298-
kvm_disable_tdp();
9299-
9300-
update_ple_window_actual_max();
9301-
93029328
return 0;
9303-
9304-
out7:
9305-
free_page((unsigned long)vmx_vmwrite_bitmap);
9306-
out6:
9307-
free_page((unsigned long)vmx_vmread_bitmap);
9308-
out5:
9309-
free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic);
9310-
out4:
9311-
free_page((unsigned long)vmx_msr_bitmap_longmode);
9312-
out3:
9313-
free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic);
9314-
out2:
9315-
free_page((unsigned long)vmx_msr_bitmap_legacy);
9316-
out1:
9317-
free_page((unsigned long)vmx_io_bitmap_b);
9318-
out:
9319-
free_page((unsigned long)vmx_io_bitmap_a);
9320-
return r;
93219329
}
93229330

93239331
static void __exit vmx_exit(void)
93249332
{
9325-
free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic);
9326-
free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic);
9327-
free_page((unsigned long)vmx_msr_bitmap_legacy);
9328-
free_page((unsigned long)vmx_msr_bitmap_longmode);
9329-
free_page((unsigned long)vmx_io_bitmap_b);
9330-
free_page((unsigned long)vmx_io_bitmap_a);
9331-
free_page((unsigned long)vmx_vmwrite_bitmap);
9332-
free_page((unsigned long)vmx_vmread_bitmap);
9333-
93349333
#ifdef CONFIG_KEXEC
93359334
RCU_INIT_POINTER(crash_vmclear_loaded_vmcss, NULL);
93369335
synchronize_rcu();

0 commit comments

Comments
 (0)