static int __init vmx_init(void)
{
    int r;

    vmx_io_bitmap_a = (unsigned long *)__get_free_page(GFP_KERNEL);
    if (!vmx_io_bitmap_a)
        return -ENOMEM;

    vmx_io_bitmap_b = (unsigned long *)__get_free_page(GFP_KERNEL);
    if (!vmx_io_bitmap_b) {
        r = -ENOMEM;
        goto out;
    }

    vmx_msr_bitmap_legacy = (unsigned long *)__get_free_page(GFP_KERNEL);
    if (!vmx_msr_bitmap_legacy) {
        r = -ENOMEM;
        goto out1;
    }

    vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL);
    if (!vmx_msr_bitmap_longmode) {
        r = -ENOMEM;
        goto out2;
    }

    /*
     * 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), THIS_MODULE);
    if (r)
        goto out3;

    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);

    if (enable_ept) {
        bypass_guest_pf = 0;
        kvm_mmu_set_base_ptes(VMX_EPT_READABLE_MASK |
            VMX_EPT_WRITABLE_MASK);
        kvm_mmu_set_mask_ptes(0ull, 0ull, 0ull, 0ull,
                VMX_EPT_EXECUTABLE_MASK);
        kvm_enable_tdp();
    } else
        kvm_disable_tdp();

    if (bypass_guest_pf)
        kvm_mmu_set_nonpresent_ptes(~0xffeull, 0ull);

    ept_sync_global();

    return 0;

out3:
    free_page((unsigned long)vmx_msr_bitmap_longmode);
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;
}

Reply via email to