kvm: x86: vmx: move down hardware_setup() and hardware_unsetup()
RFC PATCH 1/2 kvm: x86: vmx: move down hardware_setup() and hardware_unsetup()
Just move this pair of functions down to make sure later we can add something dependent on others.
Signed-off-by Tiejun Chen <[email protected]>
--- arch/x86/kvm/vmx.c | 140 ++++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 70 deletions(-)
arch/x86/kvm/vmx.c +70 -70
@@ -3110,76 +3110,6 @@ static __init int alloc_kvm_area(void)return 0 ; } -static __init int hardware_setup (void ) -{ -if (setup_vmcs_config (&vmcs_config) <0 ) -return -EIO ; - -if (boot_cpu_has (X86_FEATURE_NX )) -kvm_enable_efer_bits (EFER_NX ); - -if (!cpu_has_vmx_vpid ()) - enable_vpid =0 ; -if (!cpu_has_vmx_shadow_vmcs ()) - enable_shadow_vmcs =0 ; -if (enable_shadow_vmcs) -init_vmcs_shadow_fields (); - -if (!cpu_has_vmx_ept () || - !cpu_has_vmx_ept_4levels ()) { - enable_ept =0 ; - enable_unrestricted_guest =0 ; - enable_ept_ad_bits =0 ; - } - -if (!cpu_has_vmx_ept_ad_bits ()) - enable_ept_ad_bits =0 ; - -if (!cpu_has_vmx_unrestricted_guest ()) - enable_unrestricted_guest =0 ; - -if (!cpu_has_vmx_flexpriority ()) { - flexpriority_enabled =0 ; - -/* -* set_apic_access_page_addr() is used to reload apic access -* page upon invalidation. No need to do anything if the -* processor does not have the APIC_ACCESS_ADDR VMCS field. -*/ - kvm_x86_ops->set_apic_access_page_addr =NULL ; - } - -if (!cpu_has_vmx_tpr_shadow ()) - kvm_x86_ops->update_cr8_intercept =NULL ; - -if (enable_ept && !cpu_has_vmx_ept_2m_page ()) -kvm_disable_largepages (); - -if (!cpu_has_vmx_ple ()) - ple_gap =0 ; - -if (!cpu_has_vmx_apicv ()) - enable_apicv =0 ; - -if (enable_apicv) - kvm_x86_ops->update_cr8_intercept =NULL ; -else { - kvm_x86_ops->hwapic_irr_update =NULL ; - kvm_x86_ops->deliver_posted_interrupt =NULL ; - kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy; - } - -if (nested) -nested_vmx_setup_ctls_msrs (); - -return alloc_kvm_area (); -} - -static __exit void hardware_unsetup(void) -{ -free_kvm_area (); -} -static bool emulation_required (struct kvm_vcpu *vcpu) {return emulate_invalid_guest_state && !guest_state_valid (vcpu);
@@ -5785,6 +5715,76 @@ static void update_ple_window_actual_max(void) ple_window_grow, INT_MIN); } +static __init int hardware_setup (void ) +{ +if (setup_vmcs_config (&vmcs_config) <0 ) +return -EIO ; + +if (boot_cpu_has (X86_FEATURE_NX )) +kvm_enable_efer_bits (EFER_NX ); + +if (!cpu_has_vmx_vpid ()) + enable_vpid =0 ; +if (!cpu_has_vmx_shadow_vmcs ()) + enable_shadow_vmcs =0 ; +if (enable_shadow_vmcs) +init_vmcs_shadow_fields (); + +if (!cpu_has_vmx_ept () || + !cpu_has_vmx_ept_4levels ()) { + enable_ept =0 ; + enable_unrestricted_guest =0 ; + enable_ept_ad_bits =0 ; + } + +if (!cpu_has_vmx_ept_ad_bits ()) + enable_ept_ad_bits =0 ; + +if (!cpu_has_vmx_unrestricted_guest ()) + enable_unrestricted_guest =0 ; + +if (!cpu_has_vmx_flexpriority ()) { + flexpriority_enabled =0 ; + +/* +* set_apic_access_page_addr() is used to reload apic access +* page upon invalidation. No need to do anything if the +* processor does not have the APIC_ACCESS_ADDR VMCS field. +*/ + kvm_x86_ops->set_apic_access_page_addr =NULL ; + } + +if (!cpu_has_vmx_tpr_shadow ()) + kvm_x86_ops->update_cr8_intercept =NULL ; + +if (enable_ept && !cpu_has_vmx_ept_2m_page ()) +kvm_disable_largepages (); + +if (!cpu_has_vmx_ple ()) + ple_gap =0 ; + +if (!cpu_has_vmx_apicv ()) + enable_apicv =0 ; + +if (enable_apicv) + kvm_x86_ops->update_cr8_intercept =NULL ; +else { + kvm_x86_ops->hwapic_irr_update =NULL ; + kvm_x86_ops->deliver_posted_interrupt =NULL ; + kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy; + } + +if (nested) +nested_vmx_setup_ctls_msrs (); + +return alloc_kvm_area (); +} + +static __exit void hardware_unsetup(void) +{ +free_kvm_area (); +} +/* * Indicate a busy-waiting vcpu in spinlock. We do not enable the PAUSE * exiting, so only get here on cpu with PAUSE-Loop-Exiting.
Signature · 1 line
1.9.1
RFC PATCH 2/2 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]>
--- arch/x86/kvm/vmx.c | 267 ++++++++++++++++++++++++++--------------------------- 1 file changed, 133 insertions(+), 134 deletions(-)
arch/x86/kvm/vmx.c +133 -134
@@ -5717,8 +5717,108 @@ static void update_ple_window_actual_max(void)static __init int hardware_setup (void ) { -if (setup_vmcs_config (&vmcs_config) <0 ) -return -EIO ; +int r = -ENOMEM , i, msr; + +rdmsrl_safe (MSR_EFER , &host_efer); + +for (i =0 ; i <ARRAY_SIZE (vmx_msr_index); ++i) +kvm_define_shared_msr (i, vmx_msr_index[i]); + + vmx_io_bitmap_a = (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_io_bitmap_a) +return r; + + vmx_io_bitmap_b = (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_io_bitmap_b) + goto out; + + vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_msr_bitmap_legacy) + goto out1; + + vmx_msr_bitmap_legacy_x2apic = + (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_msr_bitmap_legacy_x2apic) + goto out2; + + vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_msr_bitmap_longmode) + goto out3; + + vmx_msr_bitmap_longmode_x2apic = + (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_msr_bitmap_longmode_x2apic) + goto out4; + vmx_vmread_bitmap = (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_vmread_bitmap) + goto out5; + + vmx_vmwrite_bitmap = (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_vmwrite_bitmap) + goto out6; + +memset (vmx_vmread_bitmap,0xff ,PAGE_SIZE ); +memset (vmx_vmwrite_bitmap,0xff ,PAGE_SIZE ); + +/* +* Allow direct access to the PC debug port (it is often used for I/O +* delays, but the vmexits simply slow things down). +*/ +memset (vmx_io_bitmap_a,0xff ,PAGE_SIZE ); +clear_bit (0x80 , vmx_io_bitmap_a); + +memset (vmx_io_bitmap_b,0xff ,PAGE_SIZE ); + +memset (vmx_msr_bitmap_legacy,0xff ,PAGE_SIZE ); +memset (vmx_msr_bitmap_longmode,0xff ,PAGE_SIZE ); + +vmx_disable_intercept_for_msr (MSR_FS_BASE , false); +vmx_disable_intercept_for_msr (MSR_GS_BASE , false); +vmx_disable_intercept_for_msr (MSR_KERNEL_GS_BASE , true); +vmx_disable_intercept_for_msr (MSR_IA32_SYSENTER_CS , false); +vmx_disable_intercept_for_msr (MSR_IA32_SYSENTER_ESP , false); +vmx_disable_intercept_for_msr (MSR_IA32_SYSENTER_EIP , false); +vmx_disable_intercept_for_msr (MSR_IA32_BNDCFGS , true); + +memcpy (vmx_msr_bitmap_legacy_x2apic, + vmx_msr_bitmap_legacy,PAGE_SIZE ); +memcpy (vmx_msr_bitmap_longmode_x2apic, + vmx_msr_bitmap_longmode,PAGE_SIZE ); + +if (enable_apicv) { +for (msr =0x800 ; msr <=0x8ff ; msr++) +vmx_disable_intercept_msr_read_x2apic (msr); + +/* According SDM, in x2apic mode, the whole id reg is used. +* But in KVM, it only use the highest eight bits. Need to +* intercept it */ +vmx_enable_intercept_msr_read_x2apic (0x802 ); +/* TMCCT */ +vmx_enable_intercept_msr_read_x2apic (0x839 ); +/* TPR */ +vmx_disable_intercept_msr_write_x2apic (0x808 ); +/* EOI */ +vmx_disable_intercept_msr_write_x2apic (0x80b ); +/* SELF-IPI */ +vmx_disable_intercept_msr_write_x2apic (0x83f ); + } + +if (enable_ept) { +kvm_mmu_set_mask_ptes (0ull , + (enable_ept_ad_bits) ?VMX_EPT_ACCESS_BIT :0ull , + (enable_ept_ad_bits) ?VMX_EPT_DIRTY_BIT :0ull , +0ull ,VMX_EPT_EXECUTABLE_MASK ); +ept_set_mmio_spte_mask (); +kvm_enable_tdp (); + }else +kvm_disable_tdp (); + +update_ple_window_actual_max (); + +if (setup_vmcs_config (&vmcs_config) <0 ) { + r = -EIO ; + goto out7; + }if (boot_cpu_has (X86_FEATURE_NX ))kvm_enable_efer_bits (EFER_NX );
@@ -5778,10 +5878,38 @@ static __init int hardware_setup(void)nested_vmx_setup_ctls_msrs ();return alloc_kvm_area (); + +out7: +free_page ((unsigned long )vmx_vmwrite_bitmap); +out6: +free_page ((unsigned long )vmx_vmread_bitmap); +out5: +free_page ((unsigned long )vmx_msr_bitmap_longmode_x2apic); +out4: +free_page ((unsigned long )vmx_msr_bitmap_longmode); +out3: +free_page ((unsigned long )vmx_msr_bitmap_legacy_x2apic); +out2: +free_page ((unsigned long )vmx_msr_bitmap_legacy); +out1: +free_page ((unsigned long )vmx_io_bitmap_b); +out: +free_page ((unsigned long )vmx_io_bitmap_a); + +return r; } static __exit void hardware_unsetup(void) { +free_page ((unsigned long )vmx_msr_bitmap_legacy_x2apic); +free_page ((unsigned long )vmx_msr_bitmap_longmode_x2apic); +free_page ((unsigned long )vmx_msr_bitmap_legacy); +free_page ((unsigned long )vmx_msr_bitmap_longmode); +free_page ((unsigned long )vmx_io_bitmap_b); +free_page ((unsigned long )vmx_io_bitmap_a); +free_page ((unsigned long )vmx_vmwrite_bitmap); +free_page ((unsigned long )vmx_vmread_bitmap); +free_kvm_area (); }
@@ -9180,150 +9308,21 @@ static struct kvm_x86_ops vmx_x86_ops = {static int __init vmx_init (void ) { -int r, i, msr; - -rdmsrl_safe (MSR_EFER , &host_efer); - -for (i =0 ; i <ARRAY_SIZE (vmx_msr_index); ++i) -kvm_define_shared_msr (i, vmx_msr_index[i]); - - vmx_io_bitmap_a = (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_io_bitmap_a) -return -ENOMEM ; - - r = -ENOMEM ; - - vmx_io_bitmap_b = (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_io_bitmap_b) - goto out; - - vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_msr_bitmap_legacy) - goto out1; - - vmx_msr_bitmap_legacy_x2apic = - (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_msr_bitmap_legacy_x2apic) - goto out2; - - vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_msr_bitmap_longmode) - goto out3; - - vmx_msr_bitmap_longmode_x2apic = - (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_msr_bitmap_longmode_x2apic) - goto out4; - vmx_vmread_bitmap = (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_vmread_bitmap) - goto out5; - - vmx_vmwrite_bitmap = (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_vmwrite_bitmap) - goto out6; - -memset (vmx_vmread_bitmap,0xff ,PAGE_SIZE ); -memset (vmx_vmwrite_bitmap,0xff ,PAGE_SIZE ); - -/* -* Allow direct access to the PC debug port (it is often used for I/O -* delays, but the vmexits simply slow things down). -*/ -memset (vmx_io_bitmap_a,0xff ,PAGE_SIZE ); -clear_bit (0x80 , vmx_io_bitmap_a); - -memset (vmx_io_bitmap_b,0xff ,PAGE_SIZE ); - -memset (vmx_msr_bitmap_legacy,0xff ,PAGE_SIZE ); -memset (vmx_msr_bitmap_longmode,0xff ,PAGE_SIZE ); - -set_bit (0 , vmx_vpid_bitmap);/* 0 is reserved for host */ - - r =kvm_init (&vmx_x86_ops,sizeof (struct vcpu_vmx ), - __alignof__(struct vcpu_vmx ),THIS_MODULE ); +int r =kvm_init (&vmx_x86_ops,sizeof (struct vcpu_vmx ), + __alignof__(struct vcpu_vmx ),THIS_MODULE );if (r) - goto out7; +return r;#ifdef CONFIG_KEXEC rcu_assign_pointer (crash_vmclear_loaded_vmcss, crash_vmclear_local_loaded_vmcss);#endif -vmx_disable_intercept_for_msr (MSR_FS_BASE , false); -vmx_disable_intercept_for_msr (MSR_GS_BASE , false); -vmx_disable_intercept_for_msr (MSR_KERNEL_GS_BASE , true); -vmx_disable_intercept_for_msr (MSR_IA32_SYSENTER_CS , false); -vmx_disable_intercept_for_msr (MSR_IA32_SYSENTER_ESP , false); -vmx_disable_intercept_for_msr (MSR_IA32_SYSENTER_EIP , false); -vmx_disable_intercept_for_msr (MSR_IA32_BNDCFGS , true); - -memcpy (vmx_msr_bitmap_legacy_x2apic, - vmx_msr_bitmap_legacy,PAGE_SIZE ); -memcpy (vmx_msr_bitmap_longmode_x2apic, - vmx_msr_bitmap_longmode,PAGE_SIZE ); - -if (enable_apicv) { -for (msr =0x800 ; msr <=0x8ff ; msr++) -vmx_disable_intercept_msr_read_x2apic (msr); - -/* According SDM, in x2apic mode, the whole id reg is used. -* But in KVM, it only use the highest eight bits. Need to -* intercept it */ -vmx_enable_intercept_msr_read_x2apic (0x802 ); -/* TMCCT */ -vmx_enable_intercept_msr_read_x2apic (0x839 ); -/* TPR */ -vmx_disable_intercept_msr_write_x2apic (0x808 ); -/* EOI */ -vmx_disable_intercept_msr_write_x2apic (0x80b ); -/* SELF-IPI */ -vmx_disable_intercept_msr_write_x2apic (0x83f ); - } - -if (enable_ept) { -kvm_mmu_set_mask_ptes (0ull , - (enable_ept_ad_bits) ?VMX_EPT_ACCESS_BIT :0ull , - (enable_ept_ad_bits) ?VMX_EPT_DIRTY_BIT :0ull , -0ull ,VMX_EPT_EXECUTABLE_MASK ); -ept_set_mmio_spte_mask (); -kvm_enable_tdp (); - }else -kvm_disable_tdp (); - -update_ple_window_actual_max (); -return 0 ; - -out7: -free_page ((unsigned long )vmx_vmwrite_bitmap); -out6: -free_page ((unsigned long )vmx_vmread_bitmap); -out5: -free_page ((unsigned long )vmx_msr_bitmap_longmode_x2apic); -out4: -free_page ((unsigned long )vmx_msr_bitmap_longmode); -out3: -free_page ((unsigned long )vmx_msr_bitmap_legacy_x2apic); -out2: -free_page ((unsigned long )vmx_msr_bitmap_legacy); -out1: -free_page ((unsigned long )vmx_io_bitmap_b); -out: -free_page ((unsigned long )vmx_io_bitmap_a); -return r; } static void __exit vmx_exit(void) { -free_page ((unsigned long )vmx_msr_bitmap_legacy_x2apic); -free_page ((unsigned long )vmx_msr_bitmap_longmode_x2apic); -free_page ((unsigned long )vmx_msr_bitmap_legacy); -free_page ((unsigned long )vmx_msr_bitmap_longmode); -free_page ((unsigned long )vmx_io_bitmap_b); -free_page ((unsigned long )vmx_io_bitmap_a); -free_page ((unsigned long )vmx_vmwrite_bitmap); -free_page ((unsigned long )vmx_vmread_bitmap); -#ifdef CONFIG_KEXEC RCU_INIT_POINTER (crash_vmclear_loaded_vmcss,NULL );synchronize_rcu ();
Signature · 1 line
1.9.1
Re: [RFC][PATCH 2/2] kvm: x86: vmx: move some vmx setting from vmx_init() to hardware_setup()
Quoted 4 lines · Tiejun Chen
Instead of
vmx_init(), actually it would make reasonable sense to do anything specific to vmx hardware setting invmx_x86_ops->hardware_setup().Signed-off-by Tiejun Chen <[email protected]>
Applied, thanks. This makes vmx_init and svm_init more similar, which is nice.
Paolo
Quoted 313 lines
--- arch/x86/kvm/vmx.c | 267 ++++++++++++++++++++++++++--------------------------- 1 file changed, 133 insertions(+), 134 deletions(-)arch/x86/kvm/vmx.c +133
-134@@ -5717,8 +5717,108 @@ static void update_ple_window_actual_max(void)static __init int hardware_setup (void ) { -if (setup_vmcs_config (&vmcs_config) <0 ) -return -EIO ; +int r = -ENOMEM , i, msr; + +rdmsrl_safe (MSR_EFER , &host_efer); + +for (i =0 ; i <ARRAY_SIZE (vmx_msr_index); ++i) +kvm_define_shared_msr (i, vmx_msr_index[i]); + + vmx_io_bitmap_a = (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_io_bitmap_a) +return r; + + vmx_io_bitmap_b = (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_io_bitmap_b) + goto out; + + vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_msr_bitmap_legacy) + goto out1; + + vmx_msr_bitmap_legacy_x2apic = + (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_msr_bitmap_legacy_x2apic) + goto out2; + + vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_msr_bitmap_longmode) + goto out3; + + vmx_msr_bitmap_longmode_x2apic = + (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_msr_bitmap_longmode_x2apic) + goto out4; + vmx_vmread_bitmap = (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_vmread_bitmap) + goto out5; + + vmx_vmwrite_bitmap = (unsigned long *)__get_free_page (GFP_KERNEL ); +if (!vmx_vmwrite_bitmap) + goto out6; + +memset (vmx_vmread_bitmap,0xff ,PAGE_SIZE ); +memset (vmx_vmwrite_bitmap,0xff ,PAGE_SIZE ); + +/* +* Allow direct access to the PC debug port (it is often used for I/O +* delays, but the vmexits simply slow things down). +*/ +memset (vmx_io_bitmap_a,0xff ,PAGE_SIZE ); +clear_bit (0x80 , vmx_io_bitmap_a); + +memset (vmx_io_bitmap_b,0xff ,PAGE_SIZE ); + +memset (vmx_msr_bitmap_legacy,0xff ,PAGE_SIZE ); +memset (vmx_msr_bitmap_longmode,0xff ,PAGE_SIZE ); + +vmx_disable_intercept_for_msr (MSR_FS_BASE , false); +vmx_disable_intercept_for_msr (MSR_GS_BASE , false); +vmx_disable_intercept_for_msr (MSR_KERNEL_GS_BASE , true); +vmx_disable_intercept_for_msr (MSR_IA32_SYSENTER_CS , false); +vmx_disable_intercept_for_msr (MSR_IA32_SYSENTER_ESP , false); +vmx_disable_intercept_for_msr (MSR_IA32_SYSENTER_EIP , false); +vmx_disable_intercept_for_msr (MSR_IA32_BNDCFGS , true); + +memcpy (vmx_msr_bitmap_legacy_x2apic, + vmx_msr_bitmap_legacy,PAGE_SIZE ); +memcpy (vmx_msr_bitmap_longmode_x2apic, + vmx_msr_bitmap_longmode,PAGE_SIZE ); + +if (enable_apicv) { +for (msr =0x800 ; msr <=0x8ff ; msr++) +vmx_disable_intercept_msr_read_x2apic (msr); + +/* According SDM, in x2apic mode, the whole id reg is used. +* But in KVM, it only use the highest eight bits. Need to +* intercept it */ +vmx_enable_intercept_msr_read_x2apic (0x802 ); +/* TMCCT */ +vmx_enable_intercept_msr_read_x2apic (0x839 ); +/* TPR */ +vmx_disable_intercept_msr_write_x2apic (0x808 ); +/* EOI */ +vmx_disable_intercept_msr_write_x2apic (0x80b ); +/* SELF-IPI */ +vmx_disable_intercept_msr_write_x2apic (0x83f ); + } + +if (enable_ept) { +kvm_mmu_set_mask_ptes (0ull , + (enable_ept_ad_bits) ?VMX_EPT_ACCESS_BIT :0ull , + (enable_ept_ad_bits) ?VMX_EPT_DIRTY_BIT :0ull , +0ull ,VMX_EPT_EXECUTABLE_MASK ); +ept_set_mmio_spte_mask (); +kvm_enable_tdp (); + }else +kvm_disable_tdp (); + +update_ple_window_actual_max (); + +if (setup_vmcs_config (&vmcs_config) <0 ) { + r = -EIO ; + goto out7; + }if (boot_cpu_has (X86_FEATURE_NX ))kvm_enable_efer_bits (EFER_NX );@@ -5778,10 +5878,38 @@ static __init int hardware_setup(void)nested_vmx_setup_ctls_msrs ();return alloc_kvm_area (); + +out7: +free_page ((unsigned long )vmx_vmwrite_bitmap); +out6: +free_page ((unsigned long )vmx_vmread_bitmap); +out5: +free_page ((unsigned long )vmx_msr_bitmap_longmode_x2apic); +out4: +free_page ((unsigned long )vmx_msr_bitmap_longmode); +out3: +free_page ((unsigned long )vmx_msr_bitmap_legacy_x2apic); +out2: +free_page ((unsigned long )vmx_msr_bitmap_legacy); +out1: +free_page ((unsigned long )vmx_io_bitmap_b); +out: +free_page ((unsigned long )vmx_io_bitmap_a); + +return r; } static __exit void hardware_unsetup(void) { +free_page ((unsigned long )vmx_msr_bitmap_legacy_x2apic); +free_page ((unsigned long )vmx_msr_bitmap_longmode_x2apic); +free_page ((unsigned long )vmx_msr_bitmap_legacy); +free_page ((unsigned long )vmx_msr_bitmap_longmode); +free_page ((unsigned long )vmx_io_bitmap_b); +free_page ((unsigned long )vmx_io_bitmap_a); +free_page ((unsigned long )vmx_vmwrite_bitmap); +free_page ((unsigned long )vmx_vmread_bitmap); +free_kvm_area (); }@@ -9180,150 +9308,21 @@ static struct kvm_x86_ops vmx_x86_ops = {static int __init vmx_init (void ) { -int r, i, msr; - -rdmsrl_safe (MSR_EFER , &host_efer); - -for (i =0 ; i <ARRAY_SIZE (vmx_msr_index); ++i) -kvm_define_shared_msr (i, vmx_msr_index[i]); - - vmx_io_bitmap_a = (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_io_bitmap_a) -return -ENOMEM ; - - r = -ENOMEM ; - - vmx_io_bitmap_b = (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_io_bitmap_b) - goto out; - - vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_msr_bitmap_legacy) - goto out1; - - vmx_msr_bitmap_legacy_x2apic = - (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_msr_bitmap_legacy_x2apic) - goto out2; - - vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_msr_bitmap_longmode) - goto out3; - - vmx_msr_bitmap_longmode_x2apic = - (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_msr_bitmap_longmode_x2apic) - goto out4; - vmx_vmread_bitmap = (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_vmread_bitmap) - goto out5; - - vmx_vmwrite_bitmap = (unsigned long *)__get_free_page (GFP_KERNEL ); -if (!vmx_vmwrite_bitmap) - goto out6; - -memset (vmx_vmread_bitmap,0xff ,PAGE_SIZE ); -memset (vmx_vmwrite_bitmap,0xff ,PAGE_SIZE ); - -/* -* Allow direct access to the PC debug port (it is often used for I/O -* delays, but the vmexits simply slow things down). -*/ -memset (vmx_io_bitmap_a,0xff ,PAGE_SIZE ); -clear_bit (0x80 , vmx_io_bitmap_a); - -memset (vmx_io_bitmap_b,0xff ,PAGE_SIZE ); - -memset (vmx_msr_bitmap_legacy,0xff ,PAGE_SIZE ); -memset (vmx_msr_bitmap_longmode,0xff ,PAGE_SIZE ); - -set_bit (0 , vmx_vpid_bitmap);/* 0 is reserved for host */ - - r =kvm_init (&vmx_x86_ops,sizeof (struct vcpu_vmx ), - __alignof__(struct vcpu_vmx ),THIS_MODULE ); +int r =kvm_init (&vmx_x86_ops,sizeof (struct vcpu_vmx ), + __alignof__(struct vcpu_vmx ),THIS_MODULE );if (r) - goto out7; +return r;#ifdef CONFIG_KEXEC rcu_assign_pointer (crash_vmclear_loaded_vmcss, crash_vmclear_local_loaded_vmcss);#endif -vmx_disable_intercept_for_msr (MSR_FS_BASE , false); -vmx_disable_intercept_for_msr (MSR_GS_BASE , false); -vmx_disable_intercept_for_msr (MSR_KERNEL_GS_BASE , true); -vmx_disable_intercept_for_msr (MSR_IA32_SYSENTER_CS , false); -vmx_disable_intercept_for_msr (MSR_IA32_SYSENTER_ESP , false); -vmx_disable_intercept_for_msr (MSR_IA32_SYSENTER_EIP , false); -vmx_disable_intercept_for_msr (MSR_IA32_BNDCFGS , true); - -memcpy (vmx_msr_bitmap_legacy_x2apic, - vmx_msr_bitmap_legacy,PAGE_SIZE ); -memcpy (vmx_msr_bitmap_longmode_x2apic, - vmx_msr_bitmap_longmode,PAGE_SIZE ); - -if (enable_apicv) { -for (msr =0x800 ; msr <=0x8ff ; msr++) -vmx_disable_intercept_msr_read_x2apic (msr); - -/* According SDM, in x2apic mode, the whole id reg is used. -* But in KVM, it only use the highest eight bits. Need to -* intercept it */ -vmx_enable_intercept_msr_read_x2apic (0x802 ); -/* TMCCT */ -vmx_enable_intercept_msr_read_x2apic (0x839 ); -/* TPR */ -vmx_disable_intercept_msr_write_x2apic (0x808 ); -/* EOI */ -vmx_disable_intercept_msr_write_x2apic (0x80b ); -/* SELF-IPI */ -vmx_disable_intercept_msr_write_x2apic (0x83f ); - } - -if (enable_ept) { -kvm_mmu_set_mask_ptes (0ull , - (enable_ept_ad_bits) ?VMX_EPT_ACCESS_BIT :0ull , - (enable_ept_ad_bits) ?VMX_EPT_DIRTY_BIT :0ull , -0ull ,VMX_EPT_EXECUTABLE_MASK ); -ept_set_mmio_spte_mask (); -kvm_enable_tdp (); - }else -kvm_disable_tdp (); - -update_ple_window_actual_max (); -return 0 ; - -out7: -free_page ((unsigned long )vmx_vmwrite_bitmap); -out6: -free_page ((unsigned long )vmx_vmread_bitmap); -out5: -free_page ((unsigned long )vmx_msr_bitmap_longmode_x2apic); -out4: -free_page ((unsigned long )vmx_msr_bitmap_longmode); -out3: -free_page ((unsigned long )vmx_msr_bitmap_legacy_x2apic); -out2: -free_page ((unsigned long )vmx_msr_bitmap_legacy); -out1: -free_page ((unsigned long )vmx_io_bitmap_b); -out: -free_page ((unsigned long )vmx_io_bitmap_a); -return r; } static void __exit vmx_exit(void) { -free_page ((unsigned long )vmx_msr_bitmap_legacy_x2apic); -free_page ((unsigned long )vmx_msr_bitmap_longmode_x2apic); -free_page ((unsigned long )vmx_msr_bitmap_legacy); -free_page ((unsigned long )vmx_msr_bitmap_longmode); -free_page ((unsigned long )vmx_io_bitmap_b); -free_page ((unsigned long )vmx_io_bitmap_a); -free_page ((unsigned long )vmx_vmwrite_bitmap); -free_page ((unsigned long )vmx_vmread_bitmap); -#ifdef CONFIG_KEXEC RCU_INIT_POINTER (crash_vmclear_loaded_vmcss,NULL );synchronize_rcu ();