From 86d968e05ee062b10fe8d597b34f5eab2e2878bd Mon Sep 17 00:00:00 2001 From: Anthony PERARD Date: Wed, 29 Oct 2014 06:51:18 +0000 Subject: [PATCH 1/1] OvmfPkg/XenBusDxe: Introduce XenBus support itself. This is a bus-like on top of XenStore. It will look for advertised ParaVirtualized devices and initialize them by producing XenBus protocol. Change in V4: - Replace the license by the commonly used file header text. - Clean XenBus.h header (remove copyright that does not belong to the file anymore; and rewrite the brief description of the file) - Fix description on the function Change in V3: - Insert to ChildList later, once populated. - Remove XENBUS_XENSTORE_NODE macro. - add comment to XenBusAddDevice and XenBusEnumerateBus about concurrency calls. - Add a description to the introduced member to the protocol. Change in V2: - comment, file header - Fix comment style - Error handling in the main init function - coding style - Fix error path in add device. Origin: FreeBSD 10.0 License: This patch adds XenBus.c which is under the MIT licence. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Anthony PERARD Acked-by: Jordan Justen git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16270 6f19259b-4bc3-4df7-8a09-765794883524 --- OvmfPkg/Include/Protocol/XenBus.h | 19 ++ OvmfPkg/XenBusDxe/XenBus.c | 372 ++++++++++++++++++++++++++++++ OvmfPkg/XenBusDxe/XenBus.h | 44 ++++ OvmfPkg/XenBusDxe/XenBusDxe.c | 66 ++++++ OvmfPkg/XenBusDxe/XenBusDxe.h | 19 ++ OvmfPkg/XenBusDxe/XenBusDxe.inf | 3 + 6 files changed, 523 insertions(+) create mode 100644 OvmfPkg/XenBusDxe/XenBus.c create mode 100644 OvmfPkg/XenBusDxe/XenBus.h diff --git a/OvmfPkg/Include/Protocol/XenBus.h b/OvmfPkg/Include/Protocol/XenBus.h index 5693b3f284..8d1fb52c22 100644 --- a/OvmfPkg/Include/Protocol/XenBus.h +++ b/OvmfPkg/Include/Protocol/XenBus.h @@ -198,6 +198,24 @@ XENSTORE_STATUS IN BOOLEAN Abort ); +/** + Set a new state for the frontend of the PV driver. + + @param This A pointer to XENBUS_PROTOCOL instance. + @param Transaction The transaction to end/commit. + @param State The new state to apply. + + @return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value + indicating the type of failure. +**/ +typedef +XENSTORE_STATUS +(EFIAPI *XENBUS_SET_STATE)( + IN XENBUS_PROTOCOL *This, + IN XENSTORE_TRANSACTION Transaction, + IN XenBusState State + ); + /** Grant access to the page Frame to the domain DomainId. @@ -322,6 +340,7 @@ struct _XENBUS_PROTOCOL { XENBUS_XS_REMOVE XsRemove; XENBUS_XS_TRANSACTION_START XsTransactionStart; XENBUS_XS_TRANSACTION_END XsTransactionEnd; + XENBUS_SET_STATE SetState; XENBUS_GRANT_ACCESS GrantAccess; XENBUS_GRANT_END_ACCESS GrantEndAccess; diff --git a/OvmfPkg/XenBusDxe/XenBus.c b/OvmfPkg/XenBusDxe/XenBus.c new file mode 100644 index 0000000000..edd2d95217 --- /dev/null +++ b/OvmfPkg/XenBusDxe/XenBus.c @@ -0,0 +1,372 @@ +/** @file + XenBus Bus driver implemtation. + + This file implement the necessary to discover and enumerate Xen PV devices + through XenStore. + + Copyright (C) 2010 Spectra Logic Corporation + Copyright (C) 2008 Doug Rabson + Copyright (C) 2005 Rusty Russell, IBM Corporation + Copyright (C) 2005 Mike Wray, Hewlett-Packard + Copyright (C) 2005 XenSource Ltd + Copyright (C) 2014, Citrix Ltd. + + This file may be distributed separately from the Linux kernel, or + incorporated into other software packages, subject to the following license: + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this source file (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, modify, + merge, publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +**/ + +#include + +#include "XenBus.h" +#include "GrantTable.h" +#include "XenStore.h" +#include "EventChannel.h" + +#include + +STATIC XENBUS_PRIVATE_DATA gXenBusPrivateData; + +STATIC XENBUS_DEVICE_PATH gXenBusDevicePathTemplate = { + .Vendor.Header.Type = HARDWARE_DEVICE_PATH, + .Vendor.Header.SubType = HW_VENDOR_DP, + .Vendor.Header.Length[0] = (UINT8) sizeof (XENBUS_DEVICE_PATH), + .Vendor.Header.Length[1] = (UINT8) (sizeof (XENBUS_DEVICE_PATH) >> 8), + .Vendor.Guid = XENBUS_PROTOCOL_GUID, + .Type = 0, + .DeviceId = 0 +}; + + +/** + Search our internal record of configured devices (not the XenStore) to + determine if the XenBus device indicated by Node is known to the system. + + @param Dev The XENBUS_DEVICE instance to search for device children. + @param Node The XenStore node path for the device to find. + + @return The XENBUS_PRIVATE_DATA of the found device if any, or NULL. + */ +STATIC +XENBUS_PRIVATE_DATA * +XenBusDeviceInitialized ( + IN XENBUS_DEVICE *Dev, + IN CONST CHAR8 *Node + ) +{ + LIST_ENTRY *Entry; + XENBUS_PRIVATE_DATA *Child; + XENBUS_PRIVATE_DATA *Result; + + if (IsListEmpty (&Dev->ChildList)) { + return NULL; + } + + Result = NULL; + for (Entry = GetFirstNode (&Dev->ChildList); + !IsNodeAtEnd (&Dev->ChildList, Entry); + Entry = GetNextNode (&Dev->ChildList, Entry)) { + Child = XENBUS_PRIVATE_DATA_FROM_LINK (Entry); + if (!AsciiStrCmp (Child->XenBusIo.Node, Node)) { + Result = Child; + break; + } + } + + return (Result); +} + +STATIC +XenbusState +XenBusReadDriverState ( + IN CONST CHAR8 *Path + ) +{ + XenbusState State; + CHAR8 *Ptr = NULL; + XENSTORE_STATUS Status; + + Status = XenStoreRead (XST_NIL, Path, "state", NULL, (VOID **)&Ptr); + if (Status != XENSTORE_STATUS_SUCCESS) { + State = XenbusStateClosed; + } else { + State = AsciiStrDecimalToUintn (Ptr); + } + + if (Ptr != NULL) { + FreePool (Ptr); + } + + return State; +} + +// +// Callers should ensure that they are only one calling XenBusAddDevice. +// +STATIC +EFI_STATUS +XenBusAddDevice ( + XENBUS_DEVICE *Dev, + CONST CHAR8 *Type, + CONST CHAR8 *Id) +{ + CHAR8 DevicePath[XENSTORE_ABS_PATH_MAX]; + XENSTORE_STATUS StatusXenStore; + XENBUS_PRIVATE_DATA *Private; + EFI_STATUS Status; + XENBUS_DEVICE_PATH *TempXenBusPath; + VOID *ChildPciIo; + + AsciiSPrint (DevicePath, sizeof (DevicePath), + "device/%a/%a", Type, Id); + + if (XenStorePathExists (XST_NIL, DevicePath, "")) { + XENBUS_PRIVATE_DATA *Child; + enum xenbus_state State; + CHAR8 *BackendPath; + + Child = XenBusDeviceInitialized (Dev, DevicePath); + if (Child != NULL) { + /* + * We are already tracking this node + */ + Status = EFI_SUCCESS; + goto out; + } + + State = XenBusReadDriverState (DevicePath); + if (State != XenbusStateInitialising) { + /* + * Device is not new, so ignore it. This can + * happen if a device is going away after + * switching to Closed. + */ + DEBUG ((EFI_D_INFO, "XenBus: Device %a ignored. " + "State %d\n", DevicePath, State)); + Status = EFI_SUCCESS; + goto out; + } + + StatusXenStore = XenStoreRead (XST_NIL, DevicePath, "backend", + NULL, (VOID **) &BackendPath); + if (StatusXenStore != XENSTORE_STATUS_SUCCESS) { + DEBUG ((EFI_D_ERROR, "xenbus: %a no backend path.\n", DevicePath)); + Status = EFI_NOT_FOUND; + goto out; + } + + Private = AllocateCopyPool (sizeof (*Private), &gXenBusPrivateData); + Private->XenBusIo.Type = AsciiStrDup (Type); + Private->XenBusIo.Node = AsciiStrDup (DevicePath); + Private->XenBusIo.Backend = BackendPath; + Private->XenBusIo.DeviceId = AsciiStrDecimalToUintn (Id); + Private->Dev = Dev; + + TempXenBusPath = AllocateCopyPool (sizeof (XENBUS_DEVICE_PATH), + &gXenBusDevicePathTemplate); + if (!AsciiStrCmp (Private->XenBusIo.Type, "vbd")) { + TempXenBusPath->Type = XENBUS_DEVICE_PATH_TYPE_VBD; + } + TempXenBusPath->DeviceId = Private->XenBusIo.DeviceId; + Private->DevicePath = (XENBUS_DEVICE_PATH *)AppendDevicePathNode ( + Dev->DevicePath, + &TempXenBusPath->Vendor.Header); + FreePool (TempXenBusPath); + + InsertTailList (&Dev->ChildList, &Private->Link); + + Status = gBS->InstallMultipleProtocolInterfaces ( + &Private->Handle, + &gEfiDevicePathProtocolGuid, Private->DevicePath, + &gXenBusProtocolGuid, &Private->XenBusIo, + NULL); + if (EFI_ERROR (Status)) { + goto ErrorInstallProtocol; + } + + Status = gBS->OpenProtocol (Dev->ControllerHandle, + &gEfiPciIoProtocolGuid, + &ChildPciIo, Dev->This->DriverBindingHandle, + Private->Handle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "open by child controller fail (%r)\n", + Status)); + goto ErrorOpenProtocolByChild; + } + } else { + DEBUG ((EFI_D_ERROR, "XenBus: does not exist: %a\n", DevicePath)); + Status = EFI_NOT_FOUND; + } + + return Status; + +ErrorOpenProtocolByChild: + gBS->UninstallMultipleProtocolInterfaces ( + &Private->Handle, + &gEfiDevicePathProtocolGuid, Private->DevicePath, + &gXenBusProtocolGuid, &Private->XenBusIo, + NULL); +ErrorInstallProtocol: + RemoveEntryList (&Private->Link); + FreePool (Private->DevicePath); + FreePool ((VOID *) Private->XenBusIo.Backend); + FreePool ((VOID *) Private->XenBusIo.Node); + FreePool ((VOID *) Private->XenBusIo.Type); + FreePool (Private); +out: + return Status; +} + +/** + Enumerate all devices of the given type on this bus. + + @param Dev A XENBUS_DEVICE instance. + @param Type String indicating the device sub-tree (e.g. "vfb", "vif") + to enumerate. + + Devices that are found are been initialize via XenBusAddDevice (). + XenBusAddDevice () ignores duplicate detects and ignores duplicate devices, + so it can be called unconditionally for any device found in the XenStore. + */ +STATIC +VOID +XenBusEnumerateDeviceType ( + XENBUS_DEVICE *Dev, + CONST CHAR8 *Type + ) +{ + CONST CHAR8 **Directory; + UINTN Index; + UINT32 Count; + XENSTORE_STATUS Status; + + Status = XenStoreListDirectory (XST_NIL, + "device", Type, + &Count, &Directory); + if (Status != XENSTORE_STATUS_SUCCESS) { + return; + } + for (Index = 0; Index < Count; Index++) { + XenBusAddDevice (Dev, Type, Directory[Index]); + } + + FreePool (Directory); +} + + +/** + Enumerate the devices on a XenBus bus and install a XenBus Protocol instance. + + Caller should ensure that it is the only one to call this function. This + function cannot be called concurrently. + + @param Dev A XENBUS_DEVICE instance. + + @return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value + indicating the type of failure. + */ +XENSTORE_STATUS +XenBusEnumerateBus ( + XENBUS_DEVICE *Dev + ) +{ + CONST CHAR8 **Types; + UINTN Index; + UINT32 Count; + XENSTORE_STATUS Status; + + Status = XenStoreListDirectory (XST_NIL, + "device", "", + &Count, &Types); + if (Status != XENSTORE_STATUS_SUCCESS) { + return Status; + } + + for (Index = 0; Index < Count; Index++) { + XenBusEnumerateDeviceType (Dev, Types[Index]); + } + + FreePool (Types); + + return XENSTORE_STATUS_SUCCESS; +} + +STATIC +XENSTORE_STATUS +EFIAPI +XenBusSetState ( + IN XENBUS_PROTOCOL *This, + IN XENSTORE_TRANSACTION Transaction, + IN enum xenbus_state NewState + ) +{ + enum xenbus_state CurrentState; + XENSTORE_STATUS Status; + CHAR8 *Temp; + + DEBUG ((EFI_D_INFO, "XenBus: Set state to %d\n", NewState)); + + Status = XenStoreRead (Transaction, This->Node, "state", NULL, (VOID **)&Temp); + if (Status != XENSTORE_STATUS_SUCCESS) { + goto Out; + } + CurrentState = AsciiStrDecimalToUintn (Temp); + FreePool (Temp); + if (CurrentState == NewState) { + goto Out; + } + + do { + Status = XenStoreSPrint (Transaction, This->Node, "state", "%d", NewState); + } while (Status == XENSTORE_STATUS_EAGAIN); + if (Status != XENSTORE_STATUS_SUCCESS) { + DEBUG ((EFI_D_ERROR, "XenBus: failed to write new state\n")); + goto Out; + } + DEBUG ((EFI_D_INFO, "XenBus: Set state to %d, done\n", NewState)); + +Out: + return Status; +} + +STATIC XENBUS_PRIVATE_DATA gXenBusPrivateData = { + .Signature = XENBUS_PRIVATE_DATA_SIGNATURE, + + .XenBusIo.XsRead = XenBusXenStoreRead, + .XenBusIo.XsBackendRead = XenBusXenStoreBackendRead, + .XenBusIo.XsPrintf = XenBusXenStoreSPrint, + .XenBusIo.XsRemove = XenBusXenStoreRemove, + .XenBusIo.XsTransactionStart = XenBusXenStoreTransactionStart, + .XenBusIo.XsTransactionEnd = XenBusXenStoreTransactionEnd, + .XenBusIo.SetState = XenBusSetState, + .XenBusIo.GrantAccess = XenBusGrantAccess, + .XenBusIo.GrantEndAccess = XenBusGrantEndAccess, + .XenBusIo.RegisterWatch = XenBusRegisterWatch, + .XenBusIo.RegisterWatchBackend = XenBusRegisterWatchBackend, + .XenBusIo.UnregisterWatch = XenBusUnregisterWatch, + .XenBusIo.WaitForWatch = XenBusWaitForWatch, + + .XenBusIo.Type = NULL, + .XenBusIo.Node = NULL, + .XenBusIo.Backend = NULL, + + .Dev = NULL +}; diff --git a/OvmfPkg/XenBusDxe/XenBus.h b/OvmfPkg/XenBusDxe/XenBus.h new file mode 100644 index 0000000000..e96439ab7b --- /dev/null +++ b/OvmfPkg/XenBusDxe/XenBus.h @@ -0,0 +1,44 @@ +/** @file + XenBus Bus driver declarations. + + Copyright (C) 2014, Citrix Ltd. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ +#ifndef _XEN_XENBUS_XENBUSB_H +#define _XEN_XENBUS_XENBUSB_H + +#include "XenBusDxe.h" + +#define XENBUS_DEVICE_PATH_TYPE_VBD 0x1 +struct _XENBUS_DEVICE_PATH { + VENDOR_DEVICE_PATH Vendor; + UINT8 Type; + UINT16 DeviceId; +}; + + +/** + Perform XenBus bus enumeration and install protocol for children. + + Caller should ensure that it is the only one to call this function. This + function cannot be called concurrently. + + @param Dev A XENBUS_DEVICE instance. + + @return On success, XENSTORE_STATUS_SUCCESS. Otherwise an errno value + indicating the type of failure. +**/ +XENSTORE_STATUS +XenBusEnumerateBus ( + XENBUS_DEVICE *Dev + ); + +#endif /* _XEN_XENBUS_XENBUSB_H */ diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.c b/OvmfPkg/XenBusDxe/XenBusDxe.c index 679fe3b592..7a7fd82d55 100644 --- a/OvmfPkg/XenBusDxe/XenBusDxe.c +++ b/OvmfPkg/XenBusDxe/XenBusDxe.c @@ -32,6 +32,7 @@ #include "XenHypercall.h" #include "GrantTable.h" #include "XenStore.h" +#include "XenBus.h" /// @@ -286,6 +287,7 @@ XenBusDxeDriverBindingStart ( EFI_PCI_IO_PROTOCOL *PciIo; EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc; UINT64 MmioAddr; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; Status = gBS->OpenProtocol ( ControllerHandle, @@ -299,11 +301,26 @@ XenBusDxeDriverBindingStart ( return Status; } + Status = gBS->OpenProtocol ( + ControllerHandle, + &gEfiDevicePathProtocolGuid, + (VOID **) &DevicePath, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER + ); + + if (EFI_ERROR (Status)) { + goto ErrorOpenningProtocol; + } + Dev = AllocateZeroPool (sizeof (*Dev)); Dev->Signature = XENBUS_DEVICE_SIGNATURE; Dev->This = This; Dev->ControllerHandle = ControllerHandle; Dev->PciIo = PciIo; + Dev->DevicePath = DevicePath; + InitializeListHead (&Dev->ChildList); EfiAcquireLock (&mMyDeviceLock); if (mMyDevice != NULL) { @@ -350,6 +367,8 @@ XenBusDxeDriverBindingStart ( Status = XenStoreInit (Dev); ASSERT_EFI_ERROR (Status); + XenBusEnumerateBus (Dev); + Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK, NotifyExitBoot, (VOID*) Dev, @@ -360,6 +379,9 @@ XenBusDxeDriverBindingStart ( ErrorAllocated: FreePool (Dev); + gBS->CloseProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, ControllerHandle); +ErrorOpenningProtocol: gBS->CloseProtocol (ControllerHandle, &gEfiPciIoProtocolGuid, This->DriverBindingHandle, ControllerHandle); return Status; @@ -400,12 +422,56 @@ XenBusDxeDriverBindingStop ( IN EFI_HANDLE *ChildHandleBuffer OPTIONAL ) { + UINTN Index; + XENBUS_PROTOCOL *XenBusIo; + XENBUS_PRIVATE_DATA *ChildData; + EFI_STATUS Status; XENBUS_DEVICE *Dev = mMyDevice; + for (Index = 0; Index < NumberOfChildren; Index++) { + Status = gBS->OpenProtocol ( + ChildHandleBuffer[Index], + &gXenBusProtocolGuid, + (VOID **) &XenBusIo, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "XenBusDxe: get children protocol failed: %r\n", Status)); + continue; + } + ChildData = XENBUS_PRIVATE_DATA_FROM_THIS (XenBusIo); + Status = gBS->DisconnectController (ChildData->Handle, NULL, NULL); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "XenBusDxe: error disconnecting child: %r\n", + Status)); + continue; + } + + Status = gBS->UninstallMultipleProtocolInterfaces ( + ChildData->Handle, + &gEfiDevicePathProtocolGuid, ChildData->DevicePath, + &gXenBusProtocolGuid, &ChildData->XenBusIo, + NULL); + ASSERT_EFI_ERROR (Status); + + FreePool ((VOID*)ChildData->XenBusIo.Type); + FreePool ((VOID*)ChildData->XenBusIo.Node); + FreePool ((VOID*)ChildData->XenBusIo.Backend); + FreePool (ChildData->DevicePath); + RemoveEntryList (&ChildData->Link); + FreePool (ChildData); + } + if (NumberOfChildren > 0) { + return EFI_SUCCESS; + } + gBS->CloseEvent (Dev->ExitBootEvent); XenStoreDeinit (Dev); XenGrantTableDeinit (Dev); + gBS->CloseProtocol (ControllerHandle, &gEfiDevicePathProtocolGuid, + This->DriverBindingHandle, ControllerHandle); gBS->CloseProtocol (ControllerHandle, &gEfiPciIoProtocolGuid, This->DriverBindingHandle, ControllerHandle); diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.h b/OvmfPkg/XenBusDxe/XenBusDxe.h index 6be5c58d92..11640223eb 100644 --- a/OvmfPkg/XenBusDxe/XenBusDxe.h +++ b/OvmfPkg/XenBusDxe/XenBusDxe.h @@ -82,6 +82,7 @@ extern EFI_COMPONENT_NAME_PROTOCOL gXenBusDxeComponentName; #define PCI_DEVICE_ID_XEN_PLATFORM 0x0001 +typedef struct _XENBUS_DEVICE_PATH XENBUS_DEVICE_PATH; typedef struct _XENBUS_DEVICE XENBUS_DEVICE; // Have the state of the driver. @@ -92,11 +93,29 @@ struct _XENBUS_DEVICE { EFI_HANDLE ControllerHandle; EFI_PCI_IO_PROTOCOL *PciIo; EFI_EVENT ExitBootEvent; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + LIST_ENTRY ChildList; VOID *Hyperpage; shared_info_t *SharedInfo; }; +// There is one of this struct allocated for every child. +#define XENBUS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('X', 'B', 'p', 'd') +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + EFI_HANDLE Handle; + XENBUS_PROTOCOL XenBusIo; + XENBUS_DEVICE *Dev; + XENBUS_DEVICE_PATH *DevicePath; +} XENBUS_PRIVATE_DATA; + +#define XENBUS_PRIVATE_DATA_FROM_THIS(a) \ + CR (a, XENBUS_PRIVATE_DATA, XenBusIo, XENBUS_PRIVATE_DATA_SIGNATURE) +#define XENBUS_PRIVATE_DATA_FROM_LINK(a) \ + CR (a, XENBUS_PRIVATE_DATA, Link, XENBUS_PRIVATE_DATA_SIGNATURE) + /* * Helpers */ diff --git a/OvmfPkg/XenBusDxe/XenBusDxe.inf b/OvmfPkg/XenBusDxe/XenBusDxe.inf index 1343808ae3..17a5a9073a 100644 --- a/OvmfPkg/XenBusDxe/XenBusDxe.inf +++ b/OvmfPkg/XenBusDxe/XenBusDxe.inf @@ -44,6 +44,9 @@ EventChannel.h XenStore.c XenStore.h + XenBus.c + XenBus.h + Helpers.c [Sources.IA32] Ia32/hypercall.S -- 2.39.2