[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 08/18] OvmfPkg/XenBusDxe: Add Grant Table functions.
There are used to grant access of pages to other Xen domains. This code originaly comes from the Xen Project, and more precisely from MiniOS. Signed-off-by: Steven Smith <sos22@xxxxxxxxx> Signed-off-by: Grzegorz Milos <gm281@xxxxxxxxx> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- Change in V2: - Adding locks - Redo the file header - Add functions comment - Add license --- OvmfPkg/XenBusDxe/GrantTable.c | 217 ++++++++++++++++++++++++++++++++++++++++ OvmfPkg/XenBusDxe/GrantTable.h | 68 +++++++++++++ OvmfPkg/XenBusDxe/XenBusDxe.c | 15 +++ OvmfPkg/XenBusDxe/XenBusDxe.inf | 2 + 4 files changed, 302 insertions(+) create mode 100644 OvmfPkg/XenBusDxe/GrantTable.c create mode 100644 OvmfPkg/XenBusDxe/GrantTable.h diff --git a/OvmfPkg/XenBusDxe/GrantTable.c b/OvmfPkg/XenBusDxe/GrantTable.c new file mode 100644 index 0000000..8b08134 --- /dev/null +++ b/OvmfPkg/XenBusDxe/GrantTable.c @@ -0,0 +1,217 @@ +/** @file + Grant Table function implementation. + + Grant Table are used to grant access to certain page of the current + VM to an other VM. + + Author: Steven Smith (sos22@xxxxxxxxx) + Changes: Grzegorz Milos (gm281@xxxxxxxxx) + Copyright (C) 2006, Cambridge University + Copyright (C) 2014, Citrix Ltd. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. +**/ +#include "XenBusDxe.h" + +#include <IndustryStandard/Xen/memory.h> + +#include "XenHypercall.h" + +#include "GrantTable.h" +#include "InterlockedCompareExchange16.h" + +#define NR_RESERVED_ENTRIES 8 + +/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */ +#define NR_GRANT_FRAMES 4 +#define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * EFI_PAGE_SIZE / sizeof(grant_entry_v1_t)) + +STATIC grant_entry_v1_t *GrantTable = NULL; +STATIC grant_ref_t GrantList[NR_GRANT_ENTRIES]; +STATIC EFI_LOCK mGrantListLock; +#ifdef GNT_DEBUG +STATIC BOOLEAN GrantInUseList[NR_GRANT_ENTRIES]; +#endif + +STATIC +VOID +XenGrantTablePutFreeEntry ( + grant_ref_t Ref + ) +{ + EfiAcquireLock (&mGrantListLock); +#ifdef GNT_DEBUG + ASSERT (GrantInUseList[Ref]); + GrantInUseList[Ref] = FALSE; +#endif + GrantList[Ref] = GrantList[0]; + GrantList[0] = Ref; + EfiReleaseLock (&mGrantListLock); +} + +STATIC +grant_ref_t +XenGrantTableGetFreeEntry ( + VOID + ) +{ + UINTN Ref; + + EfiAcquireLock (&mGrantListLock); + Ref = GrantList[0]; + ASSERT (Ref >= NR_RESERVED_ENTRIES && Ref < NR_GRANT_ENTRIES); + GrantList[0] = GrantList[Ref]; +#ifdef GNT_DEBUG + ASSERT (!GrantInUseList[Ref]); + GrantInUseList[Ref] = TRUE; +#endif + EfiReleaseLock (&mGrantListLock); + return Ref; +} + +STATIC +grant_ref_t +XenGrantTableGrantAccess ( + IN domid_t DomainId, + IN UINTN Frame, + IN BOOLEAN ReadOnly + ) +{ + grant_ref_t Ref; + UINT32 Flags; + + ASSERT (GrantTable != NULL); + Ref = XenGrantTableGetFreeEntry (); + GrantTable[Ref].frame = Frame; + GrantTable[Ref].domid = DomainId; + MemoryFence (); + Flags = GTF_permit_access; + if (ReadOnly) { + Flags |= GTF_readonly; + } + GrantTable[Ref].flags = Flags; + + return Ref; +} + +STATIC +EFI_STATUS +XenGrantTableEndAccess ( + grant_ref_t Ref + ) +{ + UINT16 Flags, OldFlags; + + ASSERT (GrantTable != NULL); + ASSERT (Ref >= NR_RESERVED_ENTRIES && Ref < NR_GRANT_ENTRIES); + + OldFlags = GrantTable[Ref].flags; + do { + if ((Flags = OldFlags) & (GTF_reading | GTF_writing)) { + DEBUG ((EFI_D_WARN, "WARNING: g.e. still in use! (%x)\n", Flags)); + return EFI_NOT_READY; + } + OldFlags = InterlockedCompareExchange16 (&GrantTable[Ref].flags, Flags, 0); + } while (OldFlags != Flags); + + XenGrantTablePutFreeEntry (Ref); + return EFI_SUCCESS; +} + +VOID +XenGrantTableInit ( + IN XENBUS_DEVICE *Dev, + IN UINT64 MmioAddr + ) +{ + xen_add_to_physmap_t Parameters; + INTN Index; + INTN ReturnCode; + +#ifdef GNT_DEBUG + SetMem(GrantInUseList, sizeof (GrantInUseList), 1); +#endif + EfiInitializeLock (&mGrantListLock, TPL_NOTIFY); + for (Index = NR_RESERVED_ENTRIES; Index < NR_GRANT_ENTRIES; Index++) { + XenGrantTablePutFreeEntry (Index); + } + + GrantTable = (VOID*)(UINTN) MmioAddr; + for (Index = 0; Index < NR_GRANT_FRAMES; Index++) { + Parameters.domid = DOMID_SELF; + Parameters.idx = Index; + Parameters.space = XENMAPSPACE_grant_table; + Parameters.gpfn = (((xen_pfn_t) GrantTable) >> EFI_PAGE_SHIFT) + Index; + ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Parameters); + if (ReturnCode != 0) { + DEBUG ((EFI_D_ERROR, "Xen GrantTable, add_to_physmap hypercall error: %d\n", ReturnCode)); + } + } +} + +VOID +XenGrantTableDeinit ( + XENBUS_DEVICE *Dev + ) +{ + INTN ReturnCode, Index; + xen_remove_from_physmap_t Parameters; + + if (GrantTable == NULL) { + return; + } + + for (Index = NR_GRANT_FRAMES - 1; Index >= 0; Index--) { + Parameters.domid = DOMID_SELF; + Parameters.gpfn = (((xen_pfn_t) GrantTable) >> EFI_PAGE_SHIFT) + Index; + DEBUG ((EFI_D_INFO, "Xen GrantTable, removing %X\n", Parameters.gpfn)); + ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_remove_from_physmap, &Parameters); + if (ReturnCode != 0) { + DEBUG ((EFI_D_ERROR, "Xen GrantTable, remove_from_physmap hypercall error: %d\n", ReturnCode)); + } + } + GrantTable = NULL; +} + +EFI_STATUS +EFIAPI +XenBusGrantAccess ( + IN XENBUS_PROTOCOL *This, + IN domid_t DomainId, + IN UINTN Frame, // MFN + IN BOOLEAN ReadOnly, + OUT grant_ref_t *RefPtr + ) +{ + *RefPtr = XenGrantTableGrantAccess (DomainId, Frame, ReadOnly); + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +XenBusGrantEndAccess ( + IN XENBUS_PROTOCOL *This, + IN grant_ref_t Ref + ) +{ + return XenGrantTableEndAccess (Ref); +} diff --git a/OvmfPkg/XenBusDxe/GrantTable.h b/OvmfPkg/XenBusDxe/GrantTable.h new file mode 100644 index 0000000..bbead2e --- /dev/null +++ b/OvmfPkg/XenBusDxe/GrantTable.h @@ -0,0 +1,68 @@ +/** @file + Grant Table function declaration. + + Grant Table are used to grant access to certain page of the current + VM to an other VM. + + Copyright (C) 2014, Citrix Ltd. +**/ +#ifndef __GNTTAB_H__ +#define __GNTTAB_H__ + +#include <IndustryStandard/Xen/grant_table.h> + +/** + Initialize the Grant Table at the address MmioAddr. + + @param Dev A pointer to XENBUS_DEVICE. + @param MmioAddr An address where the grant table can be mapped into + the guest. +**/ +VOID +XenGrantTableInit ( + IN XENBUS_DEVICE *Dev, + IN UINT64 MmioAddr + ); + +/** + Desinitilize the Grant Table. +**/ +VOID +XenGrantTableDeinit ( + IN XENBUS_DEVICE *Dev + ); + +/** + Grant access to the page Frame to the domain DomainId. + + @param This A pointer to XENBUS_PROTOCOL instance. + @param DomainId ID of the domain to grant acces to. + @param Frame Frame Number of the page to grant access to. + @param ReadOnly Provide read-only or read-write access. + @param RefPtr Reference number of the grant will be writen to this pointer. +**/ +EFI_STATUS +EFIAPI +XenBusGrantAccess ( + IN XENBUS_PROTOCOL *This, + IN domid_t DomainId, + IN UINTN Frame, // MFN + IN BOOLEAN ReadOnly, + OUT grant_ref_t *RefPtr + ); + +/** + End access to grant Ref, previously return by XenBusGrantAccess. + + @param This A pointer to XENBUS_PROTOCOL instance. + @param Ref Reference numeber of a grant previously returned by + XenBusGrantAccess. +**/ +EFI_STATUS +EFIAPI +XenBusGrantEndAccess ( + IN XENBUS_PROTOCOL *This, + IN grant_ref_t Ref + ); + +#endif /* !__GNTTAB_H__ */ diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.c b/OvmfPkg/XenBusDxe/XenBusDxe.c index 15420c8..29aadb1 100644 --- a/OvmfPkg/XenBusDxe/XenBusDxe.c +++ b/OvmfPkg/XenBusDxe/XenBusDxe.c @@ -46,6 +46,7 @@ #include "XenBusDxe.h" #include "XenHypercall.h" +#include "GrantTable.h" /// @@ -297,6 +298,8 @@ XenBusDxeDriverBindingStart ( EFI_STATUS Status; XENBUS_DEVICE *Dev; EFI_PCI_IO_PROTOCOL *PciIo; + EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc; + UINT64 MmioAddr; Status = gBS->OpenProtocol ( ControllerHandle, @@ -316,6 +319,15 @@ XenBusDxeDriverBindingStart ( Dev->ControllerHandle = ControllerHandle; Dev->PciIo = PciIo; + Status = PciIo->GetBarAttributes (PciIo, PCI_BAR_IDX1, NULL, (VOID**) &BarDesc); + ASSERT_EFI_ERROR (Status); + ASSERT (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM); + + /* Get a Memory address for mapping the Grant Table. */ + DEBUG ((EFI_D_INFO, "XenBus: BAR at %LX\n", BarDesc->AddrRangeMin)); + MmioAddr = BarDesc->AddrRangeMin; + FreePool (BarDesc); + Status = XenHyperpageInit (Dev); if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "XenBus: Unable to retrieve the hyperpage.")); @@ -330,6 +342,8 @@ XenBusDxeDriverBindingStart ( goto ErrorNoHyperpage; } + XenGrantTableInit (Dev, MmioAddr); + Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK, NotifyExitBoot, (VOID*) Dev, @@ -384,6 +398,7 @@ XenBusDxeDriverBindingStop ( XENBUS_DEVICE *Dev = mMyDevice; gBS->CloseEvent (Dev->ExitBootEvent); + XenGrantTableDeinit (Dev); gBS->CloseProtocol (ControllerHandle, &gEfiPciIoProtocolGuid, This->DriverBindingHandle, ControllerHandle); diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.inf b/OvmfPkg/XenBusDxe/XenBusDxe.inf index 612c3db..1eca168 100644 --- a/OvmfPkg/XenBusDxe/XenBusDxe.inf +++ b/OvmfPkg/XenBusDxe/XenBusDxe.inf @@ -34,6 +34,8 @@ XenHypercall.c XenHypercall.h InterlockedCompareExchange16.h + GrantTable.c + GrantTable.h [Sources.X64] X64/hypercall.S -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |