VirtualBox

Changeset 100850 in vbox for trunk


Ignore:
Timestamp:
Aug 10, 2023 12:04:43 PM (19 months ago)
Author:
vboxsync
Message:

VMM/IEM: Combined the with-in-page and alignment checks for the inlined code, making for a straigher code path for correctly aligned data accesses. bugref:10369

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h

    r100849 r100850  
    4747#endif
    4848
     49#if TMPL_MEM_TYPE_ALIGN + 1 < TMPL_MEM_TYPE_SIZE
     50# error Have not implemented TMPL_MEM_TYPE_ALIGN smaller than TMPL_MEM_TYPE_SIZE - 1.
     51#endif
     52
    4953/** @todo fix logging   */
    5054
     
    7175    RTGCPTR GCPtrEff = iemMemApplySegmentToReadJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
    7276#  if TMPL_MEM_TYPE_SIZE > 1
    73     if (RT_LIKELY((GCPtrEff & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
     77    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN) /* If aligned, it will be within the page. */
     78                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
    7479#  endif
    7580    {
     
    9095                          == pVCpu->iem.s.DataTlb.uTlbPhysRev))
    9196            {
    92 #  if TMPL_MEM_TYPE_ALIGN != 0
    93                 /*
    94                  * Alignment check:
    95                  */
    96                 /** @todo check priority \#AC vs \#PF */
    97                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
    98                 AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
    99                 if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
    100                               || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
    101                                    & pVCpu->cpum.GstCtx.eflags.u
    102                                    & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
    103                                    & X86_CR0_AM) ))
    104 #  endif
    105                 {
    106                     /*
    107                      * Fetch and return the dword
    108                      */
    109                     STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
    110                     Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
    111                     Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
    112                     TMPL_MEM_TYPE const uRet = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
    113                     Log9(("IEM RD " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uRet));
    114                     return uRet;
    115                 }
     97                /*
     98                 * Fetch and return the data.
     99                 */
     100                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
     101                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
     102                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
     103                TMPL_MEM_TYPE const uRet = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
     104                Log9(("IEM RD " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uRet));
     105                return uRet;
    116106            }
    117107        }
     
    137127     */
    138128#  if TMPL_MEM_TYPE_SIZE > 1
    139     if (RT_LIKELY((GCPtrMem & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
     129    AssertCompile(X86_CR0_AM == X86_EFL_AC);
     130    AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
     131    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN) /* If aligned, it will be within the page. */
     132                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
    140133#  endif
    141134    {
     
    156149                          == pVCpu->iem.s.DataTlb.uTlbPhysRev))
    157150            {
    158 #  if TMPL_MEM_TYPE_ALIGN != 0
    159                 /*
    160                  * Alignment check:
    161                  */
    162                 /** @todo check priority \#AC vs \#PF */
    163                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
    164                 AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
    165                 if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
    166                               || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
    167                                    & pVCpu->cpum.GstCtx.eflags.u
    168                                    & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
    169                                    & X86_CR0_AM) ))
    170 #  endif
    171                 {
    172                     /*
    173                      * Fetch and return the dword
    174                      */
    175                     STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
    176                     Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
    177                     Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
    178                     TMPL_MEM_TYPE const uRet = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
    179                     Log9(("IEM RD " TMPL_MEM_FMT_DESC " %RGv: " TMPL_MEM_FMT_TYPE "\n", GCPtrMem, uRet));
    180                     return uRet;
    181                 }
     151                /*
     152                 * Fetch and return the dword
     153                 */
     154                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
     155                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
     156                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
     157                TMPL_MEM_TYPE const uRet = *(TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
     158                Log9(("IEM RD " TMPL_MEM_FMT_DESC " %RGv: " TMPL_MEM_FMT_TYPE "\n", GCPtrMem, uRet));
     159                return uRet;
    182160            }
    183161        }
     
    212190    RTGCPTR GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
    213191#  if TMPL_MEM_TYPE_SIZE > 1
    214     if (RT_LIKELY((GCPtrEff & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
     192    AssertCompile(X86_CR0_AM == X86_EFL_AC);
     193    AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
     194    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN) /* If aligned, it will be within the page. */
     195                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
    215196#  endif
    216197    {
     
    232213                          == pVCpu->iem.s.DataTlb.uTlbPhysRev))
    233214            {
    234 #   if TMPL_MEM_TYPE_ALIGN != 0
    235                 /*
    236                  * Alignment check:
    237                  */
    238                 /** @todo check priority \#AC vs \#PF */
    239                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
    240                 AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
    241                 if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
    242                               || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
    243                                    & pVCpu->cpum.GstCtx.eflags.u
    244                                    & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
    245                               & X86_CR0_AM) ))
    246 #   endif
    247                 {
    248                     /*
    249                      * Store the dword and return.
    250                      */
    251                     STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
    252                     Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
    253                     Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
    254                     *(TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK] = uValue;
    255                     Log9(("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uValue));
    256                     return;
    257                 }
     215                /*
     216                 * Store the dword and return.
     217                 */
     218                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
     219                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
     220                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
     221                *(TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK] = uValue;
     222                Log9(("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uValue));
     223                return;
    258224            }
    259225        }
     
    280246     */
    281247#  if TMPL_MEM_TYPE_SIZE > 1
    282     if (RT_LIKELY((GCPtrMem & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
     248    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
     249                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
    283250#  endif
    284251    {
     
    300267                          == pVCpu->iem.s.DataTlb.uTlbPhysRev))
    301268            {
    302 #   if TMPL_MEM_TYPE_ALIGN != 0
    303                 /*
    304                  * Alignment check:
    305                  */
    306                 /** @todo check priority \#AC vs \#PF */
    307                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
    308                 AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
    309                 if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
    310                               || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
    311                                    & pVCpu->cpum.GstCtx.eflags.u
    312                                    & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
    313                                    & X86_CR0_AM) ))
    314 #   endif
    315                 {
    316                     /*
    317                      * Store the dword and return.
    318                      */
    319                     STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
    320                     Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
    321                     Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
    322                     *(TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK] = uValue;
    323                     Log9(("IEM WR " TMPL_MEM_FMT_DESC " %RGv: " TMPL_MEM_FMT_TYPE "\n", GCPtrMem, uValue));
    324                     return;
    325                 }
     269                /*
     270                 * Store the dword and return.
     271                 */
     272                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
     273                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
     274                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
     275                *(TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK] = uValue;
     276                Log9(("IEM WR " TMPL_MEM_FMT_DESC " %RGv: " TMPL_MEM_FMT_TYPE "\n", GCPtrMem, uValue));
     277                return;
    326278            }
    327279        }
     
    356308    RTGCPTR GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
    357309#  if TMPL_MEM_TYPE_SIZE > 1
    358     if (RT_LIKELY((GCPtrEff & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
     310    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
     311                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
    359312#  endif
    360313    {
     
    377330                          == pVCpu->iem.s.DataTlb.uTlbPhysRev))
    378331            {
    379 #   if TMPL_MEM_TYPE_ALIGN != 0
    380                 /*
    381                  * Alignment check:
    382                  */
    383                 /** @todo check priority \#AC vs \#PF */
    384                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
    385                 AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
    386                 if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
    387                               || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
    388                                    & pVCpu->cpum.GstCtx.eflags.u
    389                                    & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
    390                                    & X86_CR0_AM) ))
    391 #   endif
    392                 {
    393                     /*
    394                      * Return the address.
    395                      */
    396                     STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
    397                     Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
    398                     Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
    399                     *pbUnmapInfo = 0;
    400                     Log8(("IEM RW/map " TMPL_MEM_FMT_DESC " %d|%RGv: %p\n",
    401                           iSegReg, GCPtrMem, &pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK]));
    402                     return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
    403                 }
     332                /*
     333                 * Return the address.
     334                 */
     335                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
     336                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
     337                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
     338                *pbUnmapInfo = 0;
     339                Log8(("IEM RW/map " TMPL_MEM_FMT_DESC " %d|%RGv: %p\n",
     340                      iSegReg, GCPtrMem, &pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK]));
     341                return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
    404342            }
    405343        }
     
    426364     */
    427365#  if TMPL_MEM_TYPE_SIZE > 1
    428     if (RT_LIKELY((GCPtrMem & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
     366    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
     367                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
    429368#  endif
    430369    {
     
    447386                          == pVCpu->iem.s.DataTlb.uTlbPhysRev))
    448387            {
    449 #   if TMPL_MEM_TYPE_ALIGN != 0
    450                 /*
    451                  * Alignment check:
    452                  */
    453                 /** @todo check priority \#AC vs \#PF */
    454                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
    455                 AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
    456                 if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
    457                               || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
    458                                    & pVCpu->cpum.GstCtx.eflags.u
    459                                    & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
    460                                    & X86_CR0_AM) ))
    461 #   endif
    462                 {
    463                     /*
    464                      * Return the address.
    465                      */
    466                     STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
    467                     Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
    468                     Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
    469                     *pbUnmapInfo = 0;
    470                     Log8(("IEM RW/map " TMPL_MEM_FMT_DESC " %RGv: %p\n",
    471                           GCPtrMem, &pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK]));
    472                     return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
    473                 }
     388                /*
     389                 * Return the address.
     390                 */
     391                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
     392                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
     393                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
     394                *pbUnmapInfo = 0;
     395                Log8(("IEM RW/map " TMPL_MEM_FMT_DESC " %RGv: %p\n",
     396                      GCPtrMem, &pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK]));
     397                return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
    474398            }
    475399        }
     
    497421    RTGCPTR GCPtrEff = iemMemApplySegmentToWriteJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
    498422#  if TMPL_MEM_TYPE_SIZE > 1
    499     if (RT_LIKELY((GCPtrEff & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
     423    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
     424                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
    500425#  endif
    501426    {
     
    518443                          == pVCpu->iem.s.DataTlb.uTlbPhysRev))
    519444            {
    520 #   if TMPL_MEM_TYPE_ALIGN != 0
    521                 /*
    522                  * Alignment check:
    523                  */
    524                 /** @todo check priority \#AC vs \#PF */
    525                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
    526                 AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
    527                 if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
    528                               || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
    529                                    & pVCpu->cpum.GstCtx.eflags.u
    530                                    & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
    531                                    & X86_CR0_AM) ))
    532 #   endif
    533                 {
    534                     /*
    535                      * Return the address.
    536                      */
    537                     STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
    538                     Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
    539                     Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
    540                     *pbUnmapInfo = 0;
    541                     Log8(("IEM WO/map " TMPL_MEM_FMT_DESC " %d|%RGv: %p\n",
    542                           iSegReg, GCPtrMem, &pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK]));
    543                     return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
    544                 }
     445                /*
     446                 * Return the address.
     447                 */
     448                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
     449                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
     450                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
     451                *pbUnmapInfo = 0;
     452                Log8(("IEM WO/map " TMPL_MEM_FMT_DESC " %d|%RGv: %p\n",
     453                      iSegReg, GCPtrMem, &pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK]));
     454                return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
    545455            }
    546456        }
     
    567477     */
    568478#  if TMPL_MEM_TYPE_SIZE > 1
    569     if (RT_LIKELY((GCPtrMem & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
     479    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
     480                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
    570481#  endif
    571482    {
     
    588499                          == pVCpu->iem.s.DataTlb.uTlbPhysRev))
    589500            {
    590 #   if TMPL_MEM_TYPE_ALIGN != 0
    591                 /*
    592                  * Alignment check:
    593                  */
    594                 /** @todo check priority \#AC vs \#PF */
    595                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
    596                 AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
    597                 if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
    598                               || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
    599                                    & pVCpu->cpum.GstCtx.eflags.u
    600                                    & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
    601                                    & X86_CR0_AM) ))
    602 #   endif
    603                 {
    604                     /*
    605                      * Return the address.
    606                      */
    607                     STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
    608                     Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
    609                     Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
    610                     *pbUnmapInfo = 0;
    611                     Log8(("IEM WO/map " TMPL_MEM_FMT_DESC " %RGv: %p\n",
    612                           GCPtrMem, &pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK]));
    613                     return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
    614                 }
     501                /*
     502                 * Return the address.
     503                 */
     504                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
     505                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
     506                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
     507                *pbUnmapInfo = 0;
     508                Log8(("IEM WO/map " TMPL_MEM_FMT_DESC " %RGv: %p\n",
     509                      GCPtrMem, &pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK]));
     510                return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
    615511            }
    616512        }
     
    638534    RTGCPTR GCPtrEff = iemMemApplySegmentToReadJmp(pVCpu, iSegReg, sizeof(TMPL_MEM_TYPE), GCPtrMem);
    639535#  if TMPL_MEM_TYPE_SIZE > 1
    640     if (RT_LIKELY((GCPtrEff & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
     536    if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
     537                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrEff, TMPL_MEM_TYPE) ))
    641538#  endif
    642539    {
     
    658555                          == pVCpu->iem.s.DataTlb.uTlbPhysRev))
    659556            {
    660 #   if TMPL_MEM_TYPE_ALIGN != 0
    661                 /*
    662                  * Alignment check:
    663                  */
    664                 /** @todo check priority \#AC vs \#PF */
    665                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
    666                 AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
    667                 if (RT_LIKELY(   !(GCPtrEff & TMPL_MEM_TYPE_ALIGN)
    668                               || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
    669                                    & pVCpu->cpum.GstCtx.eflags.u
    670                                    & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
    671                                    & X86_CR0_AM) ))
    672 #   endif
    673                 {
    674                     /*
    675                      * Return the address.
    676                      */
    677                     STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
    678                     Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
    679                     Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
    680                     *pbUnmapInfo = 0;
    681                     Log9(("IEM RO/map " TMPL_MEM_FMT_DESC " %d|%RGv: %p\n",
    682                           iSegReg, GCPtrMem, &pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK]));
    683                     return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
    684                 }
     557                /*
     558                 * Return the address.
     559                 */
     560                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
     561                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
     562                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
     563                *pbUnmapInfo = 0;
     564                Log9(("IEM RO/map " TMPL_MEM_FMT_DESC " %d|%RGv: %p\n",
     565                      iSegReg, GCPtrMem, &pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK]));
     566                return (TMPL_MEM_TYPE *)&pTlbe->pbMappingR3[GCPtrEff & GUEST_PAGE_OFFSET_MASK];
    685567            }
    686568        }
     
    707589     */
    708590#  if TMPL_MEM_TYPE_SIZE > 1
    709     if (RT_LIKELY((GCPtrMem & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(TMPL_MEM_TYPE)))
     591    if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
     592                  || TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(pVCpu, GCPtrMem, TMPL_MEM_TYPE) ))
    710593#  endif
    711594    {
     
    727610                          == pVCpu->iem.s.DataTlb.uTlbPhysRev))
    728611            {
    729 #   if TMPL_MEM_TYPE_ALIGN != 0
    730                 /*
    731                  * Alignment check:
    732                  */
    733                 /** @todo check priority \#AC vs \#PF */
    734                 AssertCompile(X86_CR0_AM == X86_EFL_AC);
    735                 AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
    736                 if (RT_LIKELY(   !(GCPtrMem & TMPL_MEM_TYPE_ALIGN)
    737                               || !(  (uint32_t)pVCpu->cpum.GstCtx.cr0
    738                                    & pVCpu->cpum.GstCtx.eflags.u
    739                                    & ((IEM_GET_CPL(pVCpu) + 1U) << 16) /* IEM_GET_CPL(pVCpu) == 3 ? X86_CR0_AM : 0 */
    740                                    & X86_CR0_AM) ))
    741 #   endif
    742                 {
    743                     /*
    744                      * Return the address.
    745                      */
    746                     STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
    747                     Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
    748                     Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
    749                     *pbUnmapInfo = 0;
    750                     Log8(("IEM RO/map " TMPL_MEM_FMT_DESC " %RGv: %p\n",
    751                           GCPtrMem, &pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK]));
    752                     return (TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
    753                 }
     612                /*
     613                 * Return the address.
     614                 */
     615                STAM_STATS({pVCpu->iem.s.DataTlb.cTlbHits++;});
     616                Assert(pTlbe->pbMappingR3); /* (Only ever cleared by the owning EMT.) */
     617                Assert(!((uintptr_t)pTlbe->pbMappingR3 & GUEST_PAGE_OFFSET_MASK));
     618                *pbUnmapInfo = 0;
     619                Log8(("IEM RO/map " TMPL_MEM_FMT_DESC " %RGv: %p\n",
     620                      GCPtrMem, &pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK]));
     621                return (TMPL_MEM_TYPE const *)&pTlbe->pbMappingR3[GCPtrMem & GUEST_PAGE_OFFSET_MASK];
    754622            }
    755623        }
  • trunk/src/VBox/VMM/include/IEMInline.h

    r100848 r100850  
    34543454 * Instantiate R/W inline templates.
    34553455 */
     3456
     3457/** @def TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
     3458 * Used to check if an unaligned access is if within the page and won't
     3459 * trigger an #AC.
     3460 *
     3461 * This can be used to deal with misaligned accesses on platforms that are
     3462 * senstive to such if desires.
     3463 */
     3464AssertCompile(X86_CR0_AM == X86_EFL_AC);
     3465AssertCompile(((3U + 1U) << 16) == X86_CR0_AM);
     3466#if 1
     3467# define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) \
     3468    (   ((a_GCPtrEff) & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(a_TmplMemType) \
     3469     && !(  (uint32_t)(a_pVCpu)->cpum.GstCtx.cr0 \
     3470          & (a_pVCpu)->cpum.GstCtx.eflags.u \
     3471          & ((IEM_GET_CPL((a_pVCpu)) + 1U) << 16) /* IEM_GET_CPL(a_pVCpu) == 3 ? X86_CR0_AM : 0 */ \
     3472          & X86_CR0_AM) )
     3473#else
     3474# define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) 0
     3475#endif
     3476
     3477
    34563478#define TMPL_MEM_TYPE       uint8_t
    34573479#define TMPL_MEM_TYPE_ALIGN 0
     
    34963518#include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    34973519
     3520#undef TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
    34983521/** @} */
    34993522
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