VirtualBox

儲存庫 vbox 的更動 86477


忽略:
時間撮記:
2020-10-7 下午08:10:05 (4 年 以前)
作者:
vboxsync
svn:sync-xref-src-repo-rev:
140787
訊息:

VMM/PGM: Use atomics when updating accessed and dirty flags from the Trap0e handler code, also take the PGM lock first to reduce races. bugref:9841 bugref:9746

位置:
trunk/src/VBox/VMM
檔案:
修改 2 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r86476 r86477  
    464464    }
    465465
     466    /* Take the big lock now before we update flags. */
     467    *pfLockTaken = true;
     468    pgmLock(pVM);
     469
    466470    /*
    467471     * Set the accessed and dirty flags.
    468472     */
    469 /** @todo Use atomics here as we don't own the lock and stuff: */
     473    /** @todo Should probably use cmpxchg logic here as we're potentially racing
     474     *        other CPUs in SMP configs. (the lock isn't enough, since we take it
     475     *        after walking and the page tables could be stale already) */
    470476#   if PGM_GST_TYPE == PGM_TYPE_AMD64
    471     GstWalk.Pml4e.u     |= X86_PML4E_A;
    472     GstWalk.pPml4e->u   |= X86_PML4E_A;
    473     GstWalk.Pdpe.u      |= X86_PDPE_A;
    474     GstWalk.pPdpe->u    |= X86_PDPE_A;
     477    if (!(GstWalk.Pml4e.u & X86_PML4E_A))
     478    {
     479        GstWalk.Pml4e.u |= X86_PML4E_A;
     480        GST_ATOMIC_OR(&GstWalk.pPml4e->u, X86_PML4E_A);
     481    }
     482    if (!(GstWalk.Pdpe.u & X86_PDPE_A))
     483    {
     484        GstWalk.Pdpe.u |= X86_PDPE_A;
     485        GST_ATOMIC_OR(&GstWalk.pPdpe->u, X86_PDPE_A);
     486    }
    475487#   endif
    476488    if (GstWalk.Core.fBigPage)
     
    479491        if (uErr & X86_TRAP_PF_RW)
    480492        {
    481             GstWalk.Pde.u   |= X86_PDE4M_A | X86_PDE4M_D;
    482             GstWalk.pPde->u |= X86_PDE4M_A | X86_PDE4M_D;
     493            if ((GstWalk.Pde.u & (X86_PDE4M_A | X86_PDE4M_D)) != (X86_PDE4M_A | X86_PDE4M_D))
     494            {
     495                GstWalk.Pde.u |= X86_PDE4M_A | X86_PDE4M_D;
     496                GST_ATOMIC_OR(&GstWalk.pPde->u, X86_PDE4M_A | X86_PDE4M_D);
     497            }
    483498        }
    484499        else
    485500        {
    486             GstWalk.Pde.u   |= X86_PDE4M_A;
    487             GstWalk.pPde->u |= X86_PDE4M_A;
     501            if (!(GstWalk.Pde.u & X86_PDE4M_A))
     502            {
     503                GstWalk.Pde.u |= X86_PDE4M_A;
     504                GST_ATOMIC_OR(&GstWalk.pPde->u, X86_PDE4M_A);
     505            }
    488506        }
    489507    }
     
    491509    {
    492510        Assert(!(GstWalk.Pde.u & X86_PDE_PS));
    493         GstWalk.Pde.u   |= X86_PDE_A;
    494         GstWalk.pPde->u |= X86_PDE_A;
     511        if (!(GstWalk.Pde.u & X86_PDE_A))
     512        {
     513            GstWalk.Pde.u |= X86_PDE_A;
     514            GST_ATOMIC_OR(&GstWalk.pPde->u, X86_PDE_A);
     515        }
     516
    495517        if (uErr & X86_TRAP_PF_RW)
    496518        {
    497519#   ifdef VBOX_WITH_STATISTICS
    498             if (!GstWalk.Pte.n.u1Dirty)
     520            if (GstWalk.Pte.u & X86_PTE_D)
    499521                STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,DirtiedPage));
    500522            else
    501523                STAM_COUNTER_INC(&pVCpu->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageAlreadyDirty));
    502524#   endif
    503             GstWalk.Pte.u   |= X86_PTE_A | X86_PTE_D;
    504             GstWalk.pPte->u |= X86_PTE_A | X86_PTE_D;
     525            if ((GstWalk.Pte.u & (X86_PTE_A | X86_PTE_D)) != (X86_PTE_A | X86_PTE_D))
     526            {
     527                GstWalk.Pte.u |= X86_PTE_A | X86_PTE_D;
     528                GST_ATOMIC_OR(&GstWalk.pPte->u, X86_PTE_A | X86_PTE_D);
     529            }
    505530        }
    506531        else
    507532        {
    508             GstWalk.Pte.u   |= X86_PTE_A;
    509             GstWalk.pPte->u |= X86_PTE_A;
     533            if (!(GstWalk.Pte.u & X86_PTE_A))
     534            {
     535                GstWalk.Pte.u |= X86_PTE_A;
     536                GST_ATOMIC_OR(&GstWalk.pPte->u, X86_PTE_A);
     537            }
    510538        }
    511539        Assert(GstWalk.Pte.u == GstWalk.pPte->u);
     
    515543#  else  /* !PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) */
    516544    GSTPDE const PdeSrcDummy = { X86_PDE_P | X86_PDE_US | X86_PDE_RW | X86_PDE_A}; /** @todo eliminate this */
    517 #  endif /* !PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) */
    518545
    519546    /* Take the big lock now. */
    520547    *pfLockTaken = true;
    521548    pgmLock(pVM);
     549#  endif /* !PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) */
    522550
    523551#  ifdef PGM_WITH_MMIO_OPTIMIZATIONS
  • trunk/src/VBox/VMM/include/PGMGstDefs.h

    r82968 r86477  
    2020*   Defined Constants And Macros                                               *
    2121*******************************************************************************/
     22#undef GSTUINT
     23#undef GST_ATOMIC_OR
    2224#undef GSTPT
    2325#undef PGSTPT
     
    6769
    6870# if PGM_SHW_TYPE == PGM_TYPE_EPT
     71#  define GSTUINT                               uint64_t
     72#  define GST_ATOMIC_OR(a_pu, a_fFlags)         ASMAtomicOrU64((a_pu), (a_fFlags))
    6973#  define GSTPT                                 X86PTPAE
    7074#  define PGSTPT                                PX86PTPAE
     
    8084# else
    8185#  if PGM_SHW_TYPE == PGM_TYPE_32BIT /* Same as shadow paging, but no PGMSHWPTEPAE. */
     86#   define GSTUINT                              uint32_t
     87#   define GST_ATOMIC_OR(a_pu, a_fFlags)        ASMAtomicOrU32((a_pu), (a_fFlags))
    8288#   define GSTPT                                X86PT
    8389#   define PGSTPT                               PX86PT
     
    9096#   define GST_PTE_PG_MASK                      X86_PTE_PG_MASK
    9197#  else
     98#   define GSTUINT                              uint64_t
     99#   define GST_ATOMIC_OR(a_pu, a_fFlags)        ASMAtomicOrU64((a_pu), (a_fFlags))
    92100#   define GSTPT                                X86PTPAE
    93101#   define PGSTPT                               PX86PTPAE
     
    123131
    124132#elif PGM_GST_TYPE == PGM_TYPE_32BIT
     133# define GSTUINT                                uint32_t
     134# define GST_ATOMIC_OR(a_pu, a_fFlags)          ASMAtomicOrU32((a_pu), (a_fFlags))
    125135# define GSTPT                                  X86PT
    126136# define PGSTPT                                 PX86PT
     
    166176#elif   PGM_GST_TYPE == PGM_TYPE_PAE \
    167177     || PGM_GST_TYPE == PGM_TYPE_AMD64
     178# define GSTUINT                                uint64_t
     179# define GST_ATOMIC_OR(a_pu, a_fFlags)          ASMAtomicOrU64((a_pu), (a_fFlags))
    168180# define GSTPT                                  X86PTPAE
    169181# define PGSTPT                                 PX86PTPAE
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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