VirtualBox

Ignore:
Timestamp:
Nov 15, 2021 5:12:43 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
148290
Message:

VMM/NEM-win,SUPLib-win: Allocate large pages in SUPPageAlloc when we're allowed. bugref:10122

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/win/SUPLib-win.cpp

    r85129 r92434  
    5050#include <iprt/assert.h>
    5151#ifndef IN_SUP_HARDENED_R3
     52# include <iprt/env.h>
    5253# include <iprt/x86.h>
    5354# include <iprt/ldr.h>
     
    645646    return rc;
    646647}
     648
    647649#endif /* !IN_SUP_HARDENED_R3 */
    648 
    649650
    650651DECLHIDDEN(int) suplibOsTerm(PSUPLIBDATA pThis)
     
    662663    return VINF_SUCCESS;
    663664}
    664 
    665665
    666666#ifndef IN_SUP_HARDENED_R3
     
    728728{
    729729    NOREF(pThis);
     730
     731    /*
     732     * Do some one-time init here wrt large pages.
     733     *
     734     * Large pages requires the SeLockMemoryPrivilege, which by default (Win10,
     735     * Win11) isn't even enabled and must be gpedit'ed to be adjustable here.
     736     */
     737    if (!(cPages & 511))
     738    {
     739        static int volatile s_fCanDoLargePages = -1;
     740        int fCanDoLargePages = s_fCanDoLargePages;
     741        if (s_fCanDoLargePages != -1)
     742        { /* likely */ }
     743        else if (RTEnvExistsUtf8("VBOX_DO_NOT_USE_LARGE_PAGES")) /** @todo add flag for this instead? */
     744            s_fCanDoLargePages = fCanDoLargePages = 0;
     745        else
     746        {
     747            HANDLE hToken = NULL;
     748            if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
     749            {
     750                union
     751                {
     752                    TOKEN_PRIVILEGES s;
     753                    uint8_t abPadding[RT_UOFFSETOF(TOKEN_PRIVILEGES, Privileges) + sizeof(LUID_AND_ATTRIBUTES)];
     754                } Privileges;
     755                RT_ZERO(Privileges);
     756                Privileges.s.PrivilegeCount = 1;
     757                Privileges.s.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
     758                if (LookupPrivilegeValueW(NULL, L"SeLockMemoryPrivilege", &Privileges.s.Privileges[0].Luid))
     759                    AdjustTokenPrivileges(hToken, FALSE, &Privileges.s, 0, NULL, NULL);
     760                else
     761                    AssertFailed();
     762                CloseHandle(hToken);
     763            }
     764            else
     765                AssertFailed();
     766            s_fCanDoLargePages = fCanDoLargePages = -2;
     767        }
     768
     769        /*
     770         * Try allocate with large pages.
     771         */
     772        if (fCanDoLargePages != 0)
     773        {
     774            *ppvPages = VirtualAlloc(NULL, (size_t)cPages << PAGE_SHIFT, MEM_COMMIT | MEM_LARGE_PAGES, PAGE_EXECUTE_READWRITE);
     775            if (*ppvPages)
     776            {
     777                if (fCanDoLargePages == -2)
     778                {
     779                    s_fCanDoLargePages = 1;
     780                    LogRel(("SUPLib: MEM_LARGE_PAGES works!\n"));
     781                }
     782                LogRel2(("SUPLib: MEM_LARGE_PAGES for %p LB %p\n", *ppvPages, (size_t)cPages << PAGE_SHIFT));
     783                return VINF_SUCCESS;
     784            }
     785
     786            /* This can happen if the above AdjustTokenPrivileges failed (non-admin
     787               user), or if the privilege isn't present in the token (need gpedit). */
     788            if (GetLastError() == ERROR_PRIVILEGE_NOT_HELD)
     789            {
     790                LogRel(("SUPLib: MEM_LARGE_PAGES privilege not held.\n"));
     791                s_fCanDoLargePages = 0;
     792            }
     793            else
     794                LogRel2(("SUPLib: MEM_LARGE_PAGES allocation failed with odd status: %u\n", GetLastError()));
     795        }
     796    }
     797
     798    /*
     799     * Do a regular allocation w/o large pages.
     800     */
    730801    *ppvPages = VirtualAlloc(NULL, (size_t)cPages << PAGE_SHIFT, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    731802    if (*ppvPages)
Note: See TracChangeset for help on using the changeset viewer.

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