Revision: 16969
http://sourceforge.net/p/edk2/code/16969
Author: lersek
Date: 2015-02-28 20:32:27 +0000 (Sat, 28 Feb 2015)
Log Message:
-----------
Ovmf/Xen: refactor XenBusDxe hypercall implementation
This refactors the Xen hypercall implementation that is part of the
XenBusDxe driver, in preparation of splitting it off entirely into
a XenHypercallLib library. This involves:
- removing the dependency on XENBUS_DEVICE* pointers in the XenHypercall()
prototypes
- moving the discovered hyperpage address to a global variable
- moving XenGetSharedInfoPage() to its only user XenBusDxe.c (the shared info
page is not strictly part of the Xen hypercall interface, and is not used
by other expected users of XenHypercallLib such as the Xen console version
of SerialPortLib
- reimplement XenHypercall2() in C and move the indexing of the hyperpage
there; the existing asm implementations are renamed to __XenHypercall2() and
invoked from the new C implementation.
Contributed-under: TianoCore Contribution Agreement 1.0
Acked-by: Laszlo Ersek <[email protected]>
Reviewed-by: Anthony PERARD <[email protected]>
Signed-off-by: Ard Biesheuvel <[email protected]>
Signed-off-by: Laszlo Ersek <[email protected]>
Modified Paths:
--------------
trunk/edk2/OvmfPkg/XenBusDxe/EventChannel.c
trunk/edk2/OvmfPkg/XenBusDxe/GrantTable.c
trunk/edk2/OvmfPkg/XenBusDxe/Ia32/hypercall.nasm
trunk/edk2/OvmfPkg/XenBusDxe/X64/hypercall.nasm
trunk/edk2/OvmfPkg/XenBusDxe/XenBusDxe.c
trunk/edk2/OvmfPkg/XenBusDxe/XenBusDxe.h
trunk/edk2/OvmfPkg/XenBusDxe/XenHypercall.c
trunk/edk2/OvmfPkg/XenBusDxe/XenHypercall.h
trunk/edk2/OvmfPkg/XenBusDxe/XenStore.c
Modified: trunk/edk2/OvmfPkg/XenBusDxe/EventChannel.c
===================================================================
--- trunk/edk2/OvmfPkg/XenBusDxe/EventChannel.c 2015-02-28 20:32:16 UTC (rev
16968)
+++ trunk/edk2/OvmfPkg/XenBusDxe/EventChannel.c 2015-02-28 20:32:27 UTC (rev
16969)
@@ -28,7 +28,7 @@
evtchn_send_t Send;
Send.port = Port;
- ReturnCode = XenHypercallEventChannelOp (Dev, EVTCHNOP_send, &Send);
+ ReturnCode = XenHypercallEventChannelOp (EVTCHNOP_send, &Send);
return (UINT32)ReturnCode;
}
@@ -40,15 +40,12 @@
OUT evtchn_port_t *Port
)
{
- XENBUS_PRIVATE_DATA *Private;
evtchn_alloc_unbound_t Parameter;
UINT32 ReturnCode;
- Private = XENBUS_PRIVATE_DATA_FROM_THIS (This);
-
Parameter.dom = DOMID_SELF;
Parameter.remote_dom = DomainId;
- ReturnCode = (UINT32)XenHypercallEventChannelOp (Private->Dev,
+ ReturnCode = (UINT32)XenHypercallEventChannelOp (
EVTCHNOP_alloc_unbound,
&Parameter);
if (ReturnCode != 0) {
@@ -79,10 +76,8 @@
IN evtchn_port_t Port
)
{
- XENBUS_PRIVATE_DATA *Private;
evtchn_close_t Close;
- Private = XENBUS_PRIVATE_DATA_FROM_THIS (This);
Close.port = Port;
- return (UINT32)XenHypercallEventChannelOp (Private->Dev, EVTCHNOP_close,
&Close);
+ return (UINT32)XenHypercallEventChannelOp (EVTCHNOP_close, &Close);
}
Modified: trunk/edk2/OvmfPkg/XenBusDxe/GrantTable.c
===================================================================
--- trunk/edk2/OvmfPkg/XenBusDxe/GrantTable.c 2015-02-28 20:32:16 UTC (rev
16968)
+++ trunk/edk2/OvmfPkg/XenBusDxe/GrantTable.c 2015-02-28 20:32:27 UTC (rev
16969)
@@ -161,7 +161,7 @@
Parameters.idx = Index;
Parameters.space = XENMAPSPACE_grant_table;
Parameters.gpfn = (xen_pfn_t) ((UINTN) GrantTable >> EFI_PAGE_SHIFT) +
Index;
- ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap,
&Parameters);
+ ReturnCode = XenHypercallMemoryOp (XENMEM_add_to_physmap, &Parameters);
if (ReturnCode != 0) {
DEBUG ((EFI_D_ERROR, "Xen GrantTable, add_to_physmap hypercall error:
%d\n", ReturnCode));
}
@@ -184,7 +184,7 @@
Parameters.domid = DOMID_SELF;
Parameters.gpfn = (xen_pfn_t) ((UINTN) GrantTable >> EFI_PAGE_SHIFT) +
Index;
DEBUG ((EFI_D_INFO, "Xen GrantTable, removing %X\n", Parameters.gpfn));
- ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_remove_from_physmap,
&Parameters);
+ ReturnCode = XenHypercallMemoryOp (XENMEM_remove_from_physmap,
&Parameters);
if (ReturnCode != 0) {
DEBUG ((EFI_D_ERROR, "Xen GrantTable, remove_from_physmap hypercall
error: %d\n", ReturnCode));
}
Modified: trunk/edk2/OvmfPkg/XenBusDxe/Ia32/hypercall.nasm
===================================================================
--- trunk/edk2/OvmfPkg/XenBusDxe/Ia32/hypercall.nasm 2015-02-28 20:32:16 UTC
(rev 16968)
+++ trunk/edk2/OvmfPkg/XenBusDxe/Ia32/hypercall.nasm 2015-02-28 20:32:27 UTC
(rev 16969)
@@ -2,13 +2,13 @@
; INTN
; EFIAPI
-; XenHypercall2 (
+; __XenHypercall2 (
; IN VOID *HypercallAddr,
; IN OUT INTN Arg1,
; IN OUT INTN Arg2
; );
-global ASM_PFX(XenHypercall2)
-ASM_PFX(XenHypercall2):
+global ASM_PFX(__XenHypercall2)
+ASM_PFX(__XenHypercall2):
; Save only ebx, ecx is supposed to be a scratch register and needs to be
; saved by the caller
push ebx
Modified: trunk/edk2/OvmfPkg/XenBusDxe/X64/hypercall.nasm
===================================================================
--- trunk/edk2/OvmfPkg/XenBusDxe/X64/hypercall.nasm 2015-02-28 20:32:16 UTC
(rev 16968)
+++ trunk/edk2/OvmfPkg/XenBusDxe/X64/hypercall.nasm 2015-02-28 20:32:27 UTC
(rev 16969)
@@ -3,13 +3,13 @@
; INTN
; EFIAPI
-; XenHypercall2 (
+; __XenHypercall2 (
; IN VOID *HypercallAddr,
; IN OUT INTN Arg1,
; IN OUT INTN Arg2
; );
-global ASM_PFX(XenHypercall2)
-ASM_PFX(XenHypercall2):
+global ASM_PFX(__XenHypercall2)
+ASM_PFX(__XenHypercall2):
push rdi
push rsi
; Copy HypercallAddr to rax
Modified: trunk/edk2/OvmfPkg/XenBusDxe/XenBusDxe.c
===================================================================
--- trunk/edk2/OvmfPkg/XenBusDxe/XenBusDxe.c 2015-02-28 20:32:16 UTC (rev
16968)
+++ trunk/edk2/OvmfPkg/XenBusDxe/XenBusDxe.c 2015-02-28 20:32:27 UTC (rev
16969)
@@ -34,6 +34,8 @@
#include "XenStore.h"
#include "XenBus.h"
+#include <IndustryStandard/Xen/hvm/params.h>
+#include <IndustryStandard/Xen/memory.h>
///
/// Driver Binding Protocol instance
@@ -52,6 +54,46 @@
STATIC XENBUS_DEVICE *mMyDevice = NULL;
/**
+ Map the shared_info_t page into memory.
+
+ @param Dev A XENBUS_DEVICE instance.
+
+ @retval EFI_SUCCESS Dev->SharedInfo whill contain a pointer to
+ the shared info page
+ @retval EFI_LOAD_ERROR The shared info page could not be mapped. The
+ hypercall returned an error.
+**/
+STATIC
+EFI_STATUS
+XenGetSharedInfoPage (
+ IN OUT XENBUS_DEVICE *Dev
+ )
+{
+ xen_add_to_physmap_t Parameter;
+
+ ASSERT (Dev->SharedInfo == NULL);
+
+ Parameter.domid = DOMID_SELF;
+ Parameter.space = XENMAPSPACE_shared_info;
+ Parameter.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);
+ Parameter.gpfn = (UINTN) Dev->SharedInfo >> EFI_PAGE_SHIFT;
+ if (XenHypercallMemoryOp (XENMEM_add_to_physmap, &Parameter) != 0) {
+ FreePages (Dev->SharedInfo, 1);
+ Dev->SharedInfo = NULL;
+ return EFI_LOAD_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
Unloads an image.
@param ImageHandle Handle that identifies the image to be
unloaded.
@@ -348,7 +390,7 @@
MmioAddr = BarDesc->AddrRangeMin;
FreePool (BarDesc);
- Status = XenHyperpageInit (Dev);
+ Status = XenHyperpageInit ();
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "XenBus: Unable to retrieve the hyperpage.\n"));
Status = EFI_UNSUPPORTED;
Modified: trunk/edk2/OvmfPkg/XenBusDxe/XenBusDxe.h
===================================================================
--- trunk/edk2/OvmfPkg/XenBusDxe/XenBusDxe.h 2015-02-28 20:32:16 UTC (rev
16968)
+++ trunk/edk2/OvmfPkg/XenBusDxe/XenBusDxe.h 2015-02-28 20:32:27 UTC (rev
16969)
@@ -91,7 +91,6 @@
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
LIST_ENTRY ChildList;
- VOID *Hyperpage;
shared_info_t *SharedInfo;
};
Modified: trunk/edk2/OvmfPkg/XenBusDxe/XenHypercall.c
===================================================================
--- trunk/edk2/OvmfPkg/XenBusDxe/XenHypercall.c 2015-02-28 20:32:16 UTC (rev
16968)
+++ trunk/edk2/OvmfPkg/XenBusDxe/XenHypercall.c 2015-02-28 20:32:27 UTC (rev
16969)
@@ -23,9 +23,21 @@
#include <IndustryStandard/Xen/hvm/params.h>
#include <IndustryStandard/Xen/memory.h>
+STATIC VOID *HyperPage;
+
+//
+// Interface exposed by the ASM implementation of the core hypercall
+//
+INTN
+EFIAPI
+__XenHypercall2 (
+ IN VOID *HypercallAddr,
+ IN OUT INTN Arg1,
+ IN OUT INTN Arg2
+ );
+
EFI_STATUS
XenHyperpageInit (
- IN OUT XENBUS_DEVICE *Dev
)
{
EFI_HOB_GUID_TYPE *GuidHob;
@@ -36,24 +48,21 @@
return EFI_NOT_FOUND;
}
XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);
- Dev->Hyperpage = XenInfo->HyperPages;
+ HyperPage = XenInfo->HyperPages;
return EFI_SUCCESS;
}
UINT64
XenHypercallHvmGetParam (
- IN XENBUS_DEVICE *Dev,
IN UINT32 Index
)
{
xen_hvm_param_t Parameter;
INTN Error;
- ASSERT (Dev->Hyperpage != NULL);
-
Parameter.domid = DOMID_SELF;
Parameter.index = Index;
- Error = XenHypercall2 ((UINT8*)Dev->Hyperpage + __HYPERVISOR_hvm_op * 32,
+ Error = XenHypercall2 (__HYPERVISOR_hvm_op,
HVMOP_get_param, (INTN) &Parameter);
if (Error != 0) {
DEBUG ((EFI_D_ERROR,
@@ -66,53 +75,33 @@
INTN
XenHypercallMemoryOp (
- IN XENBUS_DEVICE *Dev,
IN UINTN Operation,
IN OUT VOID *Arguments
)
{
- ASSERT (Dev->Hyperpage != NULL);
- return XenHypercall2 ((UINT8*)Dev->Hyperpage + __HYPERVISOR_memory_op * 32,
+ return XenHypercall2 (__HYPERVISOR_memory_op,
Operation, (INTN) Arguments);
}
INTN
XenHypercallEventChannelOp (
- IN XENBUS_DEVICE *Dev,
IN INTN Operation,
IN OUT VOID *Arguments
)
{
- ASSERT (Dev->Hyperpage != NULL);
- return XenHypercall2 ((UINT8*)Dev->Hyperpage + __HYPERVISOR_event_channel_op
* 32,
+ return XenHypercall2 (__HYPERVISOR_event_channel_op,
Operation, (INTN) Arguments);
}
-EFI_STATUS
-XenGetSharedInfoPage (
- IN OUT XENBUS_DEVICE *Dev
+INTN
+EFIAPI
+XenHypercall2 (
+ IN UINTN HypercallID,
+ IN OUT INTN Arg1,
+ IN OUT INTN Arg2
)
{
- xen_add_to_physmap_t Parameter;
+ ASSERT (HyperPage != NULL);
- ASSERT (Dev->SharedInfo == NULL);
-
- Parameter.domid = DOMID_SELF;
- Parameter.space = XENMAPSPACE_shared_info;
- Parameter.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);
- Parameter.gpfn = (UINTN) Dev->SharedInfo >> EFI_PAGE_SHIFT;
- if (XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Parameter) != 0) {
- FreePages (Dev->SharedInfo, 1);
- Dev->SharedInfo = NULL;
- return EFI_LOAD_ERROR;
- }
-
- return EFI_SUCCESS;
+ return __XenHypercall2 ((UINT8*)HyperPage + HypercallID * 32, Arg1, Arg2);
}
Modified: trunk/edk2/OvmfPkg/XenBusDxe/XenHypercall.h
===================================================================
--- trunk/edk2/OvmfPkg/XenBusDxe/XenHypercall.h 2015-02-28 20:32:16 UTC (rev
16968)
+++ trunk/edk2/OvmfPkg/XenBusDxe/XenHypercall.h 2015-02-28 20:32:27 UTC (rev
16969)
@@ -18,9 +18,9 @@
/**
This function will put the two arguments in the right place (registers) and
- call HypercallAddr, which correspond to an entry in the hypercall pages.
+ invoke the hypercall identified by HypercallID.
- @param HypercallAddr A memory address where the hypercall to call is.
+ @param HypercallID The symbolic ID of the hypercall to be invoked
@param Arg1 First argument.
@param Arg2 Second argument.
@@ -29,7 +29,7 @@
INTN
EFIAPI
XenHypercall2 (
- IN VOID *HypercallAddr,
+ IN INTN HypercallID,
IN OUT INTN Arg1,
IN OUT INTN Arg2
);
@@ -44,27 +44,23 @@
**/
EFI_STATUS
XenHyperpageInit (
- XENBUS_DEVICE *Dev
);
/**
Return the value of the HVM parameter Index.
- @param Dev A XENBUS_DEVICE instance.
@param Index The parameter to get, e.g. HVM_PARAM_STORE_EVTCHN.
@return The value of the asked parameter or 0 in case of error.
**/
UINT64
XenHypercallHvmGetParam (
- XENBUS_DEVICE *Dev,
UINT32 Index
);
/**
Hypercall to do different operation on the memory.
- @param Dev A XENBUS_DEVICE instance.
@param Operation The operation number, e.g. XENMEM_add_to_physmap.
@param Arguments The arguments associated to the operation.
@@ -73,7 +69,6 @@
**/
INTN
XenHypercallMemoryOp (
- IN XENBUS_DEVICE *Dev,
IN UINTN Operation,
IN OUT VOID *Arguments
);
@@ -81,7 +76,6 @@
/**
Do an operation on the event channels.
- @param Dev A XENBUS_DEVICE instance.
@param Operation The operation number, e.g. EVTCHNOP_send.
@param Arguments The argument associated to the operation.
@@ -90,24 +84,8 @@
**/
INTN
XenHypercallEventChannelOp (
- IN XENBUS_DEVICE *Dev,
IN INTN Operation,
IN OUT VOID *Arguments
);
-/**
- Map the shared_info_t page into memory.
-
- @param Dev A XENBUS_DEVICE instance.
-
- @retval EFI_SUCCESS Dev->SharedInfo whill contain a pointer to
- the shared info page
- @retval EFI_LOAD_ERROR The shared info page could not be mapped. The
- hypercall returned an error.
-**/
-EFI_STATUS
-XenGetSharedInfoPage (
- IN OUT XENBUS_DEVICE *Dev
- );
-
#endif
Modified: trunk/edk2/OvmfPkg/XenBusDxe/XenStore.c
===================================================================
--- trunk/edk2/OvmfPkg/XenBusDxe/XenStore.c 2015-02-28 20:32:16 UTC (rev
16968)
+++ trunk/edk2/OvmfPkg/XenBusDxe/XenStore.c 2015-02-28 20:32:27 UTC (rev
16969)
@@ -1057,8 +1057,8 @@
xs.Dev = Dev;
- xs.EventChannel = (evtchn_port_t)XenHypercallHvmGetParam (Dev,
HVM_PARAM_STORE_EVTCHN);
- XenStoreGpfn = (UINTN)XenHypercallHvmGetParam (Dev, HVM_PARAM_STORE_PFN);
+ xs.EventChannel = (evtchn_port_t)XenHypercallHvmGetParam
(HVM_PARAM_STORE_EVTCHN);
+ XenStoreGpfn = (UINTN)XenHypercallHvmGetParam (HVM_PARAM_STORE_PFN);
xs.XenStore = (VOID *) (XenStoreGpfn << EFI_PAGE_SHIFT);
DEBUG ((EFI_D_INFO, "XenBusInit: XenBus rings @%p, event channel %x\n",
xs.XenStore, xs.EventChannel));
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits