[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC 04/18] OvmfPkg/XenbusDxe: Add support to make Xen Hypercalls.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx> --- OvmfPkg/XenbusDxe/X64/hypercall.S | 16 ++++++ OvmfPkg/XenbusDxe/X64/hypercall.asm | 19 +++++++ OvmfPkg/XenbusDxe/XenHypercall.c | 101 ++++++++++++++++++++++++++++++++++++ OvmfPkg/XenbusDxe/XenHypercall.h | 44 ++++++++++++++++ OvmfPkg/XenbusDxe/XenbusDxe.c | 8 +++ OvmfPkg/XenbusDxe/XenbusDxe.h | 5 ++ OvmfPkg/XenbusDxe/XenbusDxe.inf | 6 +++ 7 files changed, 199 insertions(+) create mode 100644 OvmfPkg/XenbusDxe/X64/hypercall.S create mode 100644 OvmfPkg/XenbusDxe/X64/hypercall.asm create mode 100644 OvmfPkg/XenbusDxe/XenHypercall.c create mode 100644 OvmfPkg/XenbusDxe/XenHypercall.h diff --git a/OvmfPkg/XenbusDxe/X64/hypercall.S b/OvmfPkg/XenbusDxe/X64/hypercall.S new file mode 100644 index 0000000..80982e3 --- /dev/null +++ b/OvmfPkg/XenbusDxe/X64/hypercall.S @@ -0,0 +1,16 @@ +# Hypercall with 2 arguments +# INTN +# EFIAPI +# XenHypercall2 ( +# IN VOID *hypercall_addr, +# IN OUT INTN arg1, +# IN OUT INTN arg2 +# ); +# XXX push and pop ? +ASM_GLOBAL ASM_PFX(XenHypercall2) +ASM_PFX(XenHypercall2): + movq %rcx, %rax + movq %rdx, %rdi + movq %r8, %rsi + call *%rax + ret diff --git a/OvmfPkg/XenbusDxe/X64/hypercall.asm b/OvmfPkg/XenbusDxe/X64/hypercall.asm new file mode 100644 index 0000000..8bc41a2 --- /dev/null +++ b/OvmfPkg/XenbusDxe/X64/hypercall.asm @@ -0,0 +1,19 @@ +.code + +; Hypercall with 2 arguments +; INTN +; EFIAPI +; XenHypercall2 ( +; IN VOID *hypercall_addr, +; IN OUT INTN arg1, +; IN OUT INTN arg2 +; ); +XenHypercall2 PROC + mov rax, rcx + mov rdi, rdx + mov rsi, r8 + call rax + ret +XenHypercall2 ENDP + +END diff --git a/OvmfPkg/XenbusDxe/XenHypercall.c b/OvmfPkg/XenbusDxe/XenHypercall.c new file mode 100644 index 0000000..5e98dd5 --- /dev/null +++ b/OvmfPkg/XenbusDxe/XenHypercall.c @@ -0,0 +1,101 @@ +#include <PiDxe.h> +#include <Library/HobLib.h> +#include <Guid/XenInfo.h> + +#include "XenbusDxe.h" +#include "XenHypercall.h" + +#include <IndustryStandard/Xen/hvm/params.h> +#include <IndustryStandard/Xen/memory.h> + +EFI_STATUS +XenHyperpageInit ( + XENBUS_DEVICE *Dev + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EFI_XEN_INFO *XenInfo; + + GuidHob = GetFirstGuidHob (&gEfiXenInfoGuid); + if (GuidHob == NULL) { + DEBUG ((EFI_D_INFO, "XenbusInit: No xeninfo ?\n")); + return EFI_NOT_FOUND; + } + XenInfo = (EFI_XEN_INFO*)GET_GUID_HOB_DATA (GuidHob); + Dev->Hyperpage = XenInfo->HyperPages; + return EFI_SUCCESS; +} + +UINTN +XenHypercallHvmGetParam ( + XENBUS_DEVICE *Dev, + INTN Index + ) +{ + xen_hvm_param_t xhv; + INTN error; + + ASSERT (Dev->Hyperpage != NULL); + + xhv.domid = DOMID_SELF; + xhv.index = Index; + error = XenHypercall2(Dev->Hyperpage + __HYPERVISOR_hvm_op * 32, + HVMOP_get_param, (INTN)&xhv); + if (error) { + DEBUG ((EFI_D_ERROR, "%a: error %d trying to get %d\n", __func__, + error, Index)); + return (0); + } + return (xhv.value); +} + +INTN +XenHypercallMemoryOp ( + IN XENBUS_DEVICE *Dev, + IN UINTN Operation, + IN OUT VOID *Arguments + ) +{ + ASSERT (Dev->Hyperpage != NULL); + return XenHypercall2(Dev->Hyperpage + __HYPERVISOR_memory_op * 32, + Operation, (INTN)Arguments); +} + +INTN +XenHypercallEventChannelOp ( + IN XENBUS_DEVICE *Dev, + IN INTN Operation, + IN OUT VOID *Arguments + ) +{ + ASSERT (Dev->Hyperpage != NULL); + return XenHypercall2(Dev->Hyperpage + __HYPERVISOR_event_channel_op * 32, + Operation, (INTN)Arguments); +} + +EFI_STATUS +XenGetSharedInfoPage ( + IN OUT XENBUS_DEVICE *Dev + ) +{ + struct xen_add_to_physmap xatp; + + ASSERT (Dev->SharedInfo == NULL); + + xatp.domid = DOMID_SELF; + xatp.space = XENMAPSPACE_shared_info; + xatp.idx = 0; + /* using reserved page because the page is not released when linux is + * starting because of the add_to_physmap. QEMU might try to access the + * page, and fail because it have no right to do so (segv). + */ + Dev->SharedInfo = AllocateReservedPages (1); + xatp.gpfn = (UINTN)Dev->SharedInfo >> EFI_PAGE_SHIFT; + if (XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &xatp) != 0) { + FreePages (Dev->SharedInfo, 1); + Dev->SharedInfo = NULL; + return EFI_LOAD_ERROR; + } + + return EFI_SUCCESS; +} diff --git a/OvmfPkg/XenbusDxe/XenHypercall.h b/OvmfPkg/XenbusDxe/XenHypercall.h new file mode 100644 index 0000000..1afaf73 --- /dev/null +++ b/OvmfPkg/XenbusDxe/XenHypercall.h @@ -0,0 +1,44 @@ +#ifndef __XENBUS_DXE_HYPERCALL_H__ +#define __XENBUS_DXE_HYPERCALL_H__ + +typedef struct _XENBUS_DEVICE XENBUS_DEVICE; + +INTN +EFIAPI +XenHypercall2 ( + IN VOID *hypercall_addr, + IN OUT INTN arg1, + IN OUT INTN arg2 + ); + +EFI_STATUS +XenHyperpageInit ( + XENBUS_DEVICE *Dev + ); + +UINTN +XenHypercallHvmGetParam ( + XENBUS_DEVICE *Dev, + INTN Index + ); + +INTN +XenHypercallMemoryOp ( + IN XENBUS_DEVICE *Dev, + IN UINTN Operation, + IN OUT VOID *Arguments + ); + +INTN +XenHypercallEventChannelOp ( + IN XENBUS_DEVICE *Dev, + IN INTN Operation, + IN OUT VOID *Arguments + ); + +EFI_STATUS +XenGetSharedInfoPage ( + IN OUT XENBUS_DEVICE *Dev + ); + +#endif diff --git a/OvmfPkg/XenbusDxe/XenbusDxe.c b/OvmfPkg/XenbusDxe/XenbusDxe.c index 2c3d9b8..63ea31b 100644 --- a/OvmfPkg/XenbusDxe/XenbusDxe.c +++ b/OvmfPkg/XenbusDxe/XenbusDxe.c @@ -16,6 +16,8 @@ #include "XenbusDxe.h" +#include "XenHypercall.h" + /// /// Driver Binding Protocol instance /// @@ -294,6 +296,12 @@ XenbusDxeDriverBindingStart ( Dev->This = This; Dev->ControllerHandle = ControllerHandle; + Status = XenHyperpageInit (Dev); + ASSERT_EFI_ERROR (Status); + + Status = XenGetSharedInfoPage (Dev); + ASSERT_EFI_ERROR (Status); + Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK, NotifyExitBoot, (VOID*) Dev, diff --git a/OvmfPkg/XenbusDxe/XenbusDxe.h b/OvmfPkg/XenbusDxe/XenbusDxe.h index c1ca87a..6140f94 100644 --- a/OvmfPkg/XenbusDxe/XenbusDxe.h +++ b/OvmfPkg/XenbusDxe/XenbusDxe.h @@ -71,6 +71,8 @@ extern EFI_COMPONENT_NAME_PROTOCOL gXenbusDxeComponentName; // // Other stuff // +#include <IndustryStandard/Xen/xen.h> + #define PCI_VENDOR_ID_XEN 0x5853 #define PCI_DEVICE_ID_XEN_PLATFORM 0x0001 @@ -83,6 +85,9 @@ struct _XENBUS_DEVICE { EFI_DRIVER_BINDING_PROTOCOL *This; EFI_HANDLE ControllerHandle; EFI_EVENT ExitBootEvent; + + VOID *Hyperpage; + shared_info_t *SharedInfo; }; #endif diff --git a/OvmfPkg/XenbusDxe/XenbusDxe.inf b/OvmfPkg/XenbusDxe/XenbusDxe.inf index d6685b3..8b69f93 100644 --- a/OvmfPkg/XenbusDxe/XenbusDxe.inf +++ b/OvmfPkg/XenbusDxe/XenbusDxe.inf @@ -31,6 +31,12 @@ DriverBinding.h ComponentName.c ComponentName.h + XenHypercall.c + XenHypercall.h + +[Sources.X64] + X64/hypercall.S + X64/hypercall.asm [LibraryClasses] UefiDriverEntryPoint -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |