VirtualBox

Changeset 13387

Show
Ignore:
Timestamp:
10/20/08 13:42:28 (3 months ago)
Author:
vboxsync
Message:

First sketch of functionality to create guest physical address aliases.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/VBox/iom.h

    r13373 r13387  
    213213VMMDECL(int)  IOMMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue); 
    214214VMMDECL(int)  IOMInterpretCheckPortIOAccess(PVM pVM, PCPUMCTXCORE pCtxCore, RTIOPORT Port, unsigned cb); 
    215  
     215VMMDECL(int)  IOMMMIOModifyRegion(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapped, uint64_t fPageFlags); 
     216VMMDECL(int)  IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys); 
    216217 
    217218#ifdef IN_GC 
  • trunk/include/VBox/pgm.h

    r13236 r13387  
    362362VMMDECL(int)        PGMHandlerPhysicalJoin(PVM pVM, RTGCPHYS GCPhys1, RTGCPHYS GCPhys2); 
    363363VMMDECL(int)        PGMHandlerPhysicalPageTempOff(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage); 
     364VMMDECL(int)        PGMHandlerPhysicalPageAlias(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage, RTGCPHYS GCPhysPageRemap); 
    364365VMMDECL(int)        PGMHandlerPhysicalReset(PVM pVM, RTGCPHYS GCPhys); 
    365366VMMDECL(int)        PGMHandlerPhysicalPageReset(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage); 
  • trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp

    r13366 r13387  
    3535#include "IOMInternal.h" 
    3636#include <VBox/vm.h> 
     37#include <VBox/hwaccm.h> 
    3738 
    3839#include <VBox/dis.h> 
     
    167168 * @returns VBox status code. 
    168169 * 
    169  * @param   pVM         The virtual machine (GC pointer ofcourse)
     170 * @param   pVM         The virtual machine
    170171 * @param   pRegFrame   Pointer to CPUMCTXCORE guest registers structure. 
    171172 * @param   pCpu        Disassembler CPU state. 
     
    226227 * @returns VBox status code. 
    227228 * 
    228  * @param   pVM         The virtual machine (GC pointer ofcourse)
     229 * @param   pVM         The virtual machine
    229230 * @param   pRegFrame   Pointer to CPUMCTXCORE guest registers structure. 
    230231 * @param   pCpu        Disassembler CPU state. 
     
    285286 * @returns VBox status code. 
    286287 * 
    287  * @param   pVM         The virtual machine (GC pointer ofcourse)
     288 * @param   pVM         The virtual machine
    288289 * @param   uErrorCode  CPU Error code. 
    289290 * @param   pRegFrame   Trap register frame. 
     
    518519 * @returns VBox status code. 
    519520 * 
    520  * @param   pVM         The virtual machine (GC pointer ofcourse)
     521 * @param   pVM         The virtual machine
    521522 * @param   pRegFrame   Trap register frame. 
    522523 * @param   GCPhysFault The GC physical address corresponding to pvFault. 
     
    644645 * @returns VBox status code. 
    645646 * 
    646  * @param   pVM         The virtual machine (GC pointer ofcourse)
     647 * @param   pVM         The virtual machine
    647648 * @param   pRegFrame   Trap register frame. 
    648649 * @param   GCPhysFault The GC physical address corresponding to pvFault. 
     
    692693 * @returns VBox status code. 
    693694 * 
    694  * @param   pVM         The virtual machine (GC pointer ofcourse)
     695 * @param   pVM         The virtual machine
    695696 * @param   pRegFrame   Trap register frame. 
    696697 * @param   GCPhysFault The GC physical address corresponding to pvFault. 
     
    745746 * @returns VBox status code. 
    746747 * 
    747  * @param   pVM         The virtual machine (GC pointer ofcourse)
     748 * @param   pVM         The virtual machine
    748749 * @param   pRegFrame   Trap register frame. 
    749750 * @param   GCPhysFault The GC physical address corresponding to pvFault. 
     
    834835 * @returns VBox status code. 
    835836 * 
    836  * @param   pVM         The virtual machine (GC pointer ofcourse)
     837 * @param   pVM         The virtual machine
    837838 * @param   pRegFrame   Trap register frame. 
    838839 * @param   GCPhysFault The GC physical address corresponding to pvFault. 
     
    886887 * @returns VBox status code. 
    887888 * 
    888  * @param   pVM         The virtual machine (GC pointer ofcourse)
     889 * @param   pVM         The virtual machine
    889890 * @param   pRegFrame   Trap register frame. 
    890891 * @param   GCPhysFault The GC physical address corresponding to pvFault. 
     
    936937 * @returns VBox status code. 
    937938 * 
    938  * @param   pVM         The virtual machine (GC pointer ofcourse)
     939 * @param   pVM         The virtual machine
    939940 * @param   pRegFrame   Trap register frame. 
    940941 * @param   GCPhysFault The GC physical address corresponding to pvFault. 
     
    14161417 * @retval  VINF_EM_RESCHEDULE_REM      The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr) 
    14171418 * 
    1418  * @param   pVM             The virtual machine (GC pointer ofcourse)
     1419 * @param   pVM             The virtual machine
    14191420 * @param   pRegFrame       Pointer to CPUMCTXCORE guest registers structure. 
    14201421 * @param   uPort           IO Port 
     
    15331534 * @retval  VINF_EM_RESCHEDULE_REM      The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr) 
    15341535 * 
    1535  * @param   pVM         The virtual machine (GC pointer ofcourse)
     1536 * @param   pVM         The virtual machine
    15361537 * @param   pRegFrame   Pointer to CPUMCTXCORE guest registers structure. 
    15371538 * @param   pCpu        Disassembler CPU state. 
     
    15771578 * @retval  VINF_EM_RESCHEDULE_REM      The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr) 
    15781579 * 
    1579  * @param   pVM             The virtual machine (GC pointer ofcourse)
     1580 * @param   pVM             The virtual machine
    15801581 * @param   pRegFrame       Pointer to CPUMCTXCORE guest registers structure. 
    15811582 * @param   uPort           IO Port 
     
    16961697 * @retval  VINF_EM_RESCHEDULE_REM      The exception was dispatched and cannot be executed in raw-mode. (TRPMRaiseXcptErr) 
    16971698 * 
    1698  * @param   pVM         The virtual machine (GC pointer ofcourse)
     1699 * @param   pVM         The virtual machine
    16991700 * @param   pRegFrame   Pointer to CPUMCTXCORE guest registers structure. 
    17001701 * @param   pCpu        Disassembler CPU state. 
     
    17251726} 
    17261727 
     1728#ifdef IN_RING0 
     1729/** 
     1730 * Modify an existing MMIO region page; map to another guest physical region and change the access flags 
     1731 * 
     1732 * @returns VBox status code.  
     1733 * 
     1734 * @param   pVM             The virtual machine. 
     1735 * @param   GCPhys          Physical address that's part of the MMIO region to be changed. 
     1736 * @param   GCPhysRemapped  Remapped address. 
     1737 * @param   fPageFlags      Page flags to set (typically X86_PTE_RW). 
     1738 */ 
     1739VMMDECL(int)  IOMMMIOModifyPage(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapped, uint64_t fPageFlags) 
     1740{ 
     1741    Assert(fPageFlags == X86_PTE_RW); 
     1742 
     1743    Log(("IOMMMIOModifyPage %VGp -> %VGp flags=%RX64\n", GCPhys, GCPhysRemapped, fPageFlags)); 
     1744 
     1745    /* 
     1746     * Lookup the current context range node and statistics. 
     1747     */ 
     1748    PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhys); 
     1749    AssertMsgReturn(pRange, 
     1750                    ("Handlers and page tables are out of sync or something! GCPhys=%VGp\n", GCPhys), 
     1751                    VERR_INTERNAL_ERROR); 
     1752 
     1753    GCPhys         &= 0xfff; 
     1754    GCPhysRemapped &= 0xfff; 
     1755 
     1756    /* This currently only works in real mode, protected mode without paging or with nested paging. */ 
     1757    if (    CPUMIsGuestInPagedProtectedMode(pVM) 
     1758        && !HWACCMIsNestedPagingActive(pVM)) 
     1759        return VINF_SUCCESS;    /* ignore */ 
     1760 
     1761    int rc = PGMHandlerPhysicalPageAlias(pVM, pRange->GCPhys, GCPhys, GCPhysRemapped); 
     1762    AssertRCReturn(rc, rc); 
     1763 
     1764    /* Mark it as writable and present so reads and writes no longer fault. */ 
     1765    rc = PGMShwSetPage(pVM, (RTGCPTR)GCPhys, PAGE_SIZE, X86_PTE_RW | X86_PTE_P); 
     1766    AssertRC(rc); 
     1767 
     1768    return VINF_SUCCESS; 
     1769} 
     1770 
     1771/** 
     1772 * Reset a previously modified MMIO region; restore the access flags. 
     1773 * 
     1774 * @returns VBox status code.  
     1775 * 
     1776 * @param   pVM             The virtual machine. 
     1777 * @param   GCPhys          Physical address that's part of the MMIO region to be reset. 
     1778 */ 
     1779VMMDECL(int)  IOMMMIOResetRegion(PVM pVM, RTGCPHYS GCPhys) 
     1780{ 
     1781    unsigned cb; 
     1782 
     1783    Log(("IOMMMIOResetRegion %VGp\n", GCPhys)); 
     1784    /* 
     1785     * Lookup the current context range node and statistics. 
     1786     */ 
     1787    PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhys); 
     1788    AssertMsgReturn(pRange, 
     1789                    ("Handlers and page tables are out of sync or something! GCPhys=%VGp\n", GCPhys), 
     1790                    VERR_INTERNAL_ERROR); 
     1791 
     1792    /* This currently only works in real mode, protected mode without paging or with nested paging. */ 
     1793    if (    CPUMIsGuestInPagedProtectedMode(pVM) 
     1794        && !HWACCMIsNestedPagingActive(pVM)) 
     1795        return VINF_SUCCESS;    /* ignore */ 
     1796 
     1797 
     1798    cb     = pRange->cb; 
     1799    GCPhys = pRange->GCPhys; 
     1800 
     1801    while(cb) 
     1802    { 
     1803        int rc = PGMHandlerPhysicalPageReset(pVM, pRange->GCPhys, GCPhys); 
     1804        AssertRC(rc); 
     1805 
     1806        /* Mark it as not present again to intercept all read and write access. */ 
     1807        rc = PGMShwSetPage(pVM, (RTGCPTR)GCPhys, PAGE_SIZE, 0); 
     1808        AssertRC(rc); 
     1809 
     1810        cb     -= PAGE_SIZE; 
     1811        GCPhys += PAGE_SIZE; 
     1812    } 
     1813    return VINF_SUCCESS; 
     1814} 
     1815#endif 
  • trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp

    r13232 r13387  
    884884            AssertRCReturn(rc, rc); 
    885885            PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, PGM_PAGE_HNDL_PHYS_STATE_DISABLED); 
    886 #ifdef IN_RING0 
     886#ifndef IN_GC 
     887            HWACCMInvalidatePhysPage(pVM, GCPhysPage); 
     888#endif 
     889            return VINF_SUCCESS; 
     890        } 
     891 
     892        AssertMsgFailed(("The page %#x is outside the range %#x-%#x\n", 
     893                         GCPhysPage, pCur->Core.Key, pCur->Core.KeyLast)); 
     894        return VERR_INVALID_PARAMETER; 
     895    } 
     896 
     897    AssertMsgFailed(("Specified physical handler start address %#x is invalid.\n", GCPhys)); 
     898    return VERR_PGM_HANDLER_NOT_FOUND; 
     899
     900 
     901/** 
     902 * Temporarily turns off the access monitoring of a page within an MMIO 
     903 * access handler region and remaps it to another guest physical region. 
     904 * 
     905 * Use this when no further \#PFs are required for that page. Be aware that 
     906 * a page directory sync might reset the flags, and turn on access monitoring 
     907 * for the page. 
     908 * 
     909 * The caller must do required page table modifications. 
     910 * 
     911 * @returns VBox status code. 
     912 * @param   pVM                 VM Handle 
     913 * @param   GCPhys              Start physical address earlier passed to PGMR3HandlerPhysicalRegister(). 
     914 *                              This must be a fully page aligned range or we risk messing up other 
     915 *                              handlers installed for the start and end pages. 
     916 * @param   GCPhysPage          Physical address of the page to turn off access monitoring for. 
     917 * @param   GCPhysPageRemap     Physical address of the page that serves as backing memory. 
     918 */ 
     919VMMDECL(int)  PGMHandlerPhysicalPageAlias(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysPage, RTGCPHYS GCPhysPageRemap) 
     920
     921    /* 
     922     * Validate the range. 
     923     */ 
     924    PPGMPHYSHANDLER pCur = (PPGMPHYSHANDLER)RTAvlroGCPhysGet(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, GCPhys); 
     925    if (RT_LIKELY(pCur)) 
     926    { 
     927        if (RT_LIKELY(    GCPhysPage >= pCur->Core.Key 
     928                      &&  GCPhysPage <= pCur->Core.KeyLast)) 
     929        { 
     930            Assert(!(pCur->Core.Key & PAGE_OFFSET_MASK)); 
     931            Assert((pCur->Core.KeyLast & PAGE_OFFSET_MASK) == PAGE_OFFSET_MASK); 
     932 
     933            AssertReturn(pCur->enmType == PGMPHYSHANDLERTYPE_MMIO, VERR_ACCESS_DENIED); 
     934 
     935            PPGMPAGE pPageRemap; 
     936            int rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhysPageRemap, &pPageRemap); 
     937            AssertRCReturn(rc, rc); 
     938 
     939            /* 
     940             * Change the page status. 
     941             */ 
     942            PPGMPAGE pPage; 
     943            rc = pgmPhysGetPageEx(&pVM->pgm.s, GCPhysPage, &pPage); 
     944            AssertRCReturn(rc, rc); 
     945 
     946            /* Do the actual remapping here. This page now serves as an alias for the backing memory specified. */ 
     947            pPage->HCPhys = pPageRemap->HCPhys; 
     948 
     949            PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, PGM_PAGE_HNDL_PHYS_STATE_DISABLED); 
     950#ifndef IN_GC 
    887951            HWACCMInvalidatePhysPage(pVM, GCPhysPage); 
    888952#endif 
     
    928992 
    929993            AssertReturn(   pCur->enmType == PGMPHYSHANDLERTYPE_PHYSICAL_WRITE 
    930                          || pCur->enmType == PGMPHYSHANDLERTYPE_PHYSICAL_ALL, 
     994                         || pCur->enmType == PGMPHYSHANDLERTYPE_PHYSICAL_ALL 
     995                         || pCur->enmType == PGMPHYSHANDLERTYPE_MMIO, 
    931996                         VERR_ACCESS_DENIED); 
    932997 
     
    9381003            AssertRCReturn(rc, rc); 
    9391004            PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, pgmHandlerPhysicalCalcState(pCur)); 
     1005#ifndef IN_GC 
     1006            HWACCMInvalidatePhysPage(pVM, GCPhysPage); 
     1007#endif 
    9401008            return VINF_SUCCESS; 
    9411009        } 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy