|
[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 |