|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH RFC 08/18] OvmfPkg/XenbusDxe: Add Grant Table functions.
On Wed, Jul 16, 2014 at 04:15:37PM +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.
Should you mention something about its license?
>
> 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 ?
You just need some form of locking. If EFI has some simple Mutex() you can
use that.
> +#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?
Didn't you just do that?
> + 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);
I think we have a spec somewhere for this device. Do you think
it might make sense to reference it here?
> + ASSERT_EFI_ERROR (Status);
> + ASSERT (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM);
I sooo hope the spec mandates that it is always this type of BAR.
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |