[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 08/18] OvmfPkg/XenBusDxe: Add Grant Table functions.
On Thu, Sep 04, 2014 at 05:51:03PM +0100, Anthony PERARD wrote: > 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> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@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 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |