VirtualBox

Changeset 67136 in vbox for trunk/src


Ignore:
Timestamp:
May 30, 2017 7:58:21 AM (8 years ago)
Author:
vboxsync
Message:

HostDrivers/Support, VMM: bugref:8864: On Linux 4.12 the GDT is mapped read-only. The writable-mapped GDT is available and is used for clearing the TSS BUSY descriptor bit and for LTR.

Location:
trunk/src/VBox
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp

    r66581 r67136  
    199199    { "SUPR0SuspendVTxOnCpu",                   (void *)(uintptr_t)SUPR0SuspendVTxOnCpu },
    200200    { "SUPR0ResumeVTxOnCpu",                    (void *)(uintptr_t)SUPR0ResumeVTxOnCpu },
     201    { "SUPR0GetCurrentGdtRw",                   (void *)(uintptr_t)SUPR0GetCurrentGdtRw },
    201202    { "SUPR0GetKernelFeatures",                 (void *)(uintptr_t)SUPR0GetKernelFeatures },
    202203    { "SUPR0GetPagingMode",                     (void *)(uintptr_t)SUPR0GetPagingMode },
     
    38773878
    38783879
     3880SUPR0DECL(int) SUPR0GetCurrentGdtRw(RTHCUINTPTR *pGdtRw)
     3881{
     3882#ifdef RT_OS_LINUX
     3883    return supdrvOSetCurrentGdtRw(pGdtRw);
     3884#else
     3885    return VERR_NOT_IMPLEMENTED;
     3886#endif
     3887}
     3888
     3889
    38793890/**
    38803891 * Checks if Intel VT-x feature is usable on this CPU.
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r64872 r67136  
    842842bool VBOXCALL   supdrvOSSuspendVTxOnCpu(void);
    843843void VBOXCALL   supdrvOSResumeVTxOnCpu(bool fSuspended);
     844int  VBOXCALL   supdrvOSetCurrentGdtRw(RTHCUINTPTR *pGdtRw);
    844845
    845846/**
  • trunk/src/VBox/HostDrivers/Support/linux/SUPDrv-linux.c

    r62694 r67136  
    6161# include <asm/msr.h>
    6262#endif
     63
     64#include <asm/desc.h>
    6365
    6466#include <iprt/asm-amd64-x86.h>
     
    14011403    fFlags |= SUPKERNELFEATURES_GDT_READ_ONLY;
    14021404#endif
     1405#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
     1406    fFlags |= SUPKERNELFEATURES_GDT_NEED_WRITABLE;
     1407#endif
    14031408#if defined(VBOX_STRICT) || defined(VBOX_WITH_EFLAGS_AC_SET_IN_VBOXDRV)
    14041409    fFlags |= SUPKERNELFEATURES_SMAP;
     
    14111416
    14121417
     1418int supdrvOSetCurrentGdtRw(RTHCUINTPTR *pGdtRw)
     1419{
     1420#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
     1421    *pGdtRw = (RTHCUINTPTR)get_current_gdt_rw();
     1422    return VINF_SUCCESS;
     1423#else
     1424    return VERR_NOT_IMPLEMENTED;
     1425#endif
     1426}
     1427
     1428
    14131429module_init(VBoxDrvLinuxInit);
    14141430module_exit(VBoxDrvLinuxUnload);
  • trunk/src/VBox/VMM/VMMR0/HMR0A.asm

    r66878 r67136  
    285285    mov         ax, dx
    286286    and         eax, X86_SEL_MASK_OFF_RPL                       ; Mask away TI and RPL bits leaving only the descriptor offset.
     287    test        edi, VMX_RESTORE_HOST_GDT_READ_ONLY | VMX_RESTORE_HOST_GDT_NEED_WRITABLE
     288    jnz         .gdt_readonly
    287289    add         rax, qword [rsi + VMXRESTOREHOST.HostGdtr + 2]  ; xAX <- descriptor offset + GDTR.pGdt.
    288     test        edi, VMX_RESTORE_HOST_GDT_READ_ONLY
    289     jnz         .gdt_readonly
    290290    and         dword [rax + 4], ~RT_BIT(9)                     ; Clear the busy flag in TSS desc (bits 0-7=base, bit 9=busy bit).
    291291    ltr         dx
    292292    jmp short   .test_fs
    293293.gdt_readonly:
     294    test        edi, VMX_RESTORE_HOST_GDT_NEED_WRITABLE
     295    jnz         .gdt_readonly_need_writable
    294296    mov         rcx, cr0
    295297    mov         r9, rcx
     298    add         rax, qword [rsi + VMXRESTOREHOST.HostGdtr + 2]  ; xAX <- descriptor offset + GDTR.pGdt.
    296299    and         rcx, ~X86_CR0_WP
    297300    mov         cr0, rcx
     
    299302    ltr         dx
    300303    mov         cr0, r9
     304    jmp short   .test_fs
     305.gdt_readonly_need_writable:
     306    add         rax, qword [rsi + VMXRESTOREHOST.HostGdtrRw + 2]  ; xAX <- descriptor offset + GDTR.pGdtRw.
     307    and         dword [rax + 4], ~RT_BIT(9)                     ; Clear the busy flag in TSS desc (bits 0-7=base, bit 9=busy bit).
     308    lgdt        [rsi + VMXRESTOREHOST.HostGdtrRw]
     309    ltr         dx
     310    lgdt        [rsi + VMXRESTOREHOST.HostGdtr]                 ; Load the original GDT
    301311
    302312.test_fs:
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r67050 r67136  
    30383038     */
    30393039    if (Gdtr.cbGdt != 0xffff)
    3040     {
    30413040        pVCpu->hm.s.vmx.fRestoreHostFlags |= VMX_RESTORE_HOST_GDTR;
    3042         AssertCompile(sizeof(Gdtr) == sizeof(X86XDTR64));
    3043         memcpy(&pVCpu->hm.s.vmx.RestoreHost.HostGdtr, &Gdtr, sizeof(X86XDTR64));
    3044     }
    30453041
    30463042    /*
     
    30943090            pVCpu->hm.s.vmx.fRestoreHostFlags |= VMX_RESTORE_HOST_GDT_READ_ONLY;
    30953091        pVCpu->hm.s.vmx.RestoreHost.uHostSelTR = uSelTR;
    3096 
    3097         /* Store the GDTR here as we need it while restoring TR. */
     3092    }
     3093
     3094    /*
     3095     * Store the GDTR as we need it when restoring the GDT and while restoring the TR.
     3096     */
     3097    if (pVCpu->hm.s.vmx.fRestoreHostFlags & (VMX_RESTORE_HOST_GDTR | VMX_RESTORE_HOST_SEL_TR))
     3098    {
     3099        AssertCompile(sizeof(Gdtr) == sizeof(X86XDTR64));
    30983100        memcpy(&pVCpu->hm.s.vmx.RestoreHost.HostGdtr, &Gdtr, sizeof(X86XDTR64));
     3101        if (pVM->hm.s.fHostKernelFeatures & SUPKERNELFEATURES_GDT_NEED_WRITABLE)
     3102        {
     3103            /* The GDT is read-only but the writable GDT is available. */
     3104            pVCpu->hm.s.vmx.fRestoreHostFlags |= VMX_RESTORE_HOST_GDT_NEED_WRITABLE;
     3105            pVCpu->hm.s.vmx.RestoreHost.HostGdtrRw.cb = Gdtr.cbGdt;
     3106            rc = SUPR0GetCurrentGdtRw(&pVCpu->hm.s.vmx.RestoreHost.HostGdtrRw.uAddr);
     3107            AssertRCReturn(rc, rc);
     3108        }
    30993109    }
    31003110#else
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette