VirtualBox

Changeset 13387 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Oct 20, 2008 11:42:28 AM (16 years ago)
Author:
vboxsync
Message:

First sketch of functionality to create guest physical address aliases.

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

Legend:

Unmodified
Added
Removed
  • 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        }
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