[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC 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> --- OvmfPkg/XenbusDxe/GrantTable.c | 204 ++++++++++++++++++++++++++++++++++++++++ OvmfPkg/XenbusDxe/GrantTable.h | 34 +++++++ OvmfPkg/XenbusDxe/XenbusDxe.c | 15 +++ OvmfPkg/XenbusDxe/XenbusDxe.inf | 2 + 4 files changed, 255 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..97bd15a --- /dev/null +++ b/OvmfPkg/XenbusDxe/GrantTable.c @@ -0,0 +1,204 @@ +/* + **************************************************************************** + * (C) 2006 - Cambridge University + **************************************************************************** + * + * File: GrantTable.c + * Author: Steven Smith (sos22@xxxxxxxxx) + * Changes: Grzegorz Milos (gm281@xxxxxxxxx) + * + * Date: July 2006 + * + * Environment: Xen Minimal OS + * Description: Simple grant tables implementation. About as stupid as it's + * possible to be and still work. + * + **************************************************************************** + */ +#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]; +#ifdef GNT_DEBUG +STATIC BOOLEAN GrantInUseList[NR_GRANT_ENTRIES]; +#endif + +STATIC +VOID +XenGrantTablePutFreeEntry ( + grant_ref_t Ref + ) +{ + //local_irq_save(flags); + /* MemoryFence (); */ + // lock ? +#ifdef GNT_DEBUG + ASSERT (GrantInUseList[Ref]); + GrantInUseList[Ref] = FALSE; +#endif + GrantList[Ref] = GrantList[0]; + GrantList[0] = Ref; + //local_irq_restore(flags); + /* MemoryFence (); */ +} + +STATIC +grant_ref_t +XenGrantTableGetFreeEntry ( + VOID + ) +{ + UINTN Ref; + /* local_irq_save(flags); */ + // lock ?? + 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 + /* local_irq_restore(flags); */ + 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 Args; + INTN Index; + INTN ReturnCode; + +#ifdef GNT_DEBUG + SetMem(GrantInUseList, sizeof (GrantInUseList), 1); +#endif + for (Index = NR_RESERVED_ENTRIES; Index < NR_GRANT_ENTRIES; Index++) { + XenGrantTablePutFreeEntry (Index); + } + + GrantTable = (VOID*)(UINTN) MmioAddr; + for (Index = 0; Index < NR_GRANT_FRAMES; Index++) { + Args.domid = DOMID_SELF; + Args.idx = Index; + Args.space = XENMAPSPACE_grant_table; + Args.gpfn = (((xen_pfn_t) GrantTable) >> EFI_PAGE_SHIFT) + Index; + ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Args); + 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 Args; + + if (GrantTable == NULL) { + return; + } + + for (Index = NR_GRANT_FRAMES - 1; Index >= 0; Index--) { + Args.domid = DOMID_SELF; + Args.gpfn = (((xen_pfn_t) GrantTable) >> EFI_PAGE_SHIFT) + Index; + DEBUG ((EFI_D_INFO, "%a %d, removing %X\n", __func__, __LINE__, Args.gpfn)); + ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_remove_from_physmap, &Args); + if (ReturnCode != 0) { + DEBUG ((EFI_D_ERROR, "Xen GrantTable, remove_from_physmap hypercall error: %d\n", ReturnCode)); + } + } + // XXX remove it from the physmap? + 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..05ab4be --- /dev/null +++ b/OvmfPkg/XenbusDxe/GrantTable.h @@ -0,0 +1,34 @@ +#ifndef __GNTTAB_H__ +#define __GNTTAB_H__ + +#include <IndustryStandard/Xen/grant_table.h> + +VOID +XenGrantTableInit ( + IN XENBUS_DEVICE *Dev, + IN UINT64 MmioAddr + ); + +VOID +XenGrantTableDeinit ( + IN XENBUS_DEVICE *Dev + ); + +EFI_STATUS +EFIAPI +XenbusGrantAccess ( + IN XENBUS_PROTOCOL *This, + IN domid_t DomainId, + IN UINTN Frame, // MFN + IN BOOLEAN ReadOnly, + OUT grant_ref_t *RefPtr + ); + +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 ba5e8f4..b19055d 100644 --- a/OvmfPkg/XenbusDxe/XenbusDxe.c +++ b/OvmfPkg/XenbusDxe/XenbusDxe.c @@ -17,6 +17,7 @@ #include "XenbusDxe.h" #include "XenHypercall.h" +#include "GrantTable.h" /// /// Driver Binding Protocol instance @@ -291,6 +292,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, @@ -310,12 +313,23 @@ 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, "%a, bar at %LX\n", __func__, BarDesc->AddrRangeMin)); + MmioAddr = BarDesc->AddrRangeMin; + FreePool (BarDesc); + Status = XenHyperpageInit (Dev); ASSERT_EFI_ERROR (Status); Status = XenGetSharedInfoPage (Dev); ASSERT_EFI_ERROR (Status); + XenGrantTableInit (Dev, MmioAddr); + Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK, NotifyExitBoot, (VOID*) Dev, @@ -364,6 +378,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 8f58821..093932b 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 |