]> git.proxmox.com Git - mirror_edk2.git/commitdiff
Ovmf/Xen: refactor XenBusDxe hypercall implementation
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Sat, 28 Feb 2015 20:32:27 +0000 (20:32 +0000)
committerlersek <lersek@Edk2>
Sat, 28 Feb 2015 20:32:27 +0000 (20:32 +0000)
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 <lersek@redhat.com>
Reviewed-by: Anthony PERARD <anthony.perard@citrix.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16969 6f19259b-4bc3-4df7-8a09-765794883524

OvmfPkg/XenBusDxe/EventChannel.c
OvmfPkg/XenBusDxe/GrantTable.c
OvmfPkg/XenBusDxe/Ia32/hypercall.nasm
OvmfPkg/XenBusDxe/X64/hypercall.nasm
OvmfPkg/XenBusDxe/XenBusDxe.c
OvmfPkg/XenBusDxe/XenBusDxe.h
OvmfPkg/XenBusDxe/XenHypercall.c
OvmfPkg/XenBusDxe/XenHypercall.h
OvmfPkg/XenBusDxe/XenStore.c

index 03efaf9cb90417440a8d711074ed4ee4898a66fa..a86323e6adfd5667aa5db1c7233d5f17f444e83f 100644 (file)
@@ -28,7 +28,7 @@ XenEventChannelNotify (
   evtchn_send_t Send;\r
 \r
   Send.port = Port;\r
-  ReturnCode = XenHypercallEventChannelOp (Dev, EVTCHNOP_send, &Send);\r
+  ReturnCode = XenHypercallEventChannelOp (EVTCHNOP_send, &Send);\r
   return (UINT32)ReturnCode;\r
 }\r
 \r
@@ -40,15 +40,12 @@ XenBusEventChannelAllocate (
   OUT evtchn_port_t   *Port\r
   )\r
 {\r
-  XENBUS_PRIVATE_DATA *Private;\r
   evtchn_alloc_unbound_t Parameter;\r
   UINT32 ReturnCode;\r
 \r
-  Private = XENBUS_PRIVATE_DATA_FROM_THIS (This);\r
-\r
   Parameter.dom = DOMID_SELF;\r
   Parameter.remote_dom = DomainId;\r
-  ReturnCode = (UINT32)XenHypercallEventChannelOp (Private->Dev,\r
+  ReturnCode = (UINT32)XenHypercallEventChannelOp (\r
                                    EVTCHNOP_alloc_unbound,\r
                                    &Parameter);\r
   if (ReturnCode != 0) {\r
@@ -79,10 +76,8 @@ XenBusEventChannelClose (
   IN evtchn_port_t   Port\r
   )\r
 {\r
-  XENBUS_PRIVATE_DATA *Private;\r
   evtchn_close_t Close;\r
 \r
-  Private = XENBUS_PRIVATE_DATA_FROM_THIS (This);\r
   Close.port = Port;\r
-  return (UINT32)XenHypercallEventChannelOp (Private->Dev, EVTCHNOP_close, &Close);\r
+  return (UINT32)XenHypercallEventChannelOp (EVTCHNOP_close, &Close);\r
 }\r
index 8405edc51bc4c6c82825eabe9f18ee0b70df1fce..53cb99f0e004db879c0727055de1fef754c2760f 100644 (file)
@@ -161,7 +161,7 @@ XenGrantTableInit (
     Parameters.idx = Index;\r
     Parameters.space = XENMAPSPACE_grant_table;\r
     Parameters.gpfn = (xen_pfn_t) ((UINTN) GrantTable >> EFI_PAGE_SHIFT) + Index;\r
-    ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Parameters);\r
+    ReturnCode = XenHypercallMemoryOp (XENMEM_add_to_physmap, &Parameters);\r
     if (ReturnCode != 0) {\r
       DEBUG ((EFI_D_ERROR, "Xen GrantTable, add_to_physmap hypercall error: %d\n", ReturnCode));\r
     }\r
@@ -184,7 +184,7 @@ XenGrantTableDeinit (
     Parameters.domid = DOMID_SELF;\r
     Parameters.gpfn = (xen_pfn_t) ((UINTN) GrantTable >> EFI_PAGE_SHIFT) + Index;\r
     DEBUG ((EFI_D_INFO, "Xen GrantTable, removing %X\n", Parameters.gpfn));\r
-    ReturnCode = XenHypercallMemoryOp (Dev, XENMEM_remove_from_physmap, &Parameters);\r
+    ReturnCode = XenHypercallMemoryOp (XENMEM_remove_from_physmap, &Parameters);\r
     if (ReturnCode != 0) {\r
       DEBUG ((EFI_D_ERROR, "Xen GrantTable, remove_from_physmap hypercall error: %d\n", ReturnCode));\r
     }\r
index 8547c30b81ee6f3ba2f46bc9c118471cf3d063e7..e0fa71bb5ba8a4c19aa09247db29943eeec91257 100644 (file)
@@ -2,13 +2,13 @@ SECTION .text
 \r
 ; INTN\r
 ; EFIAPI\r
-; XenHypercall2 (\r
+; __XenHypercall2 (\r
 ;   IN     VOID *HypercallAddr,\r
 ;   IN OUT INTN Arg1,\r
 ;   IN OUT INTN Arg2\r
 ;   );\r
-global ASM_PFX(XenHypercall2)\r
-ASM_PFX(XenHypercall2):\r
+global ASM_PFX(__XenHypercall2)\r
+ASM_PFX(__XenHypercall2):\r
   ; Save only ebx, ecx is supposed to be a scratch register and needs to be\r
   ; saved by the caller\r
   push ebx\r
index 177f271ef094b74fe4f034e9dbf8d25ad8f55fe8..5e6a0c05c5c407a1912ce4d54db46d2edf8de374 100644 (file)
@@ -3,13 +3,13 @@ SECTION .text
 \r
 ; INTN\r
 ; EFIAPI\r
-; XenHypercall2 (\r
+; __XenHypercall2 (\r
 ;   IN     VOID *HypercallAddr,\r
 ;   IN OUT INTN Arg1,\r
 ;   IN OUT INTN Arg2\r
 ;   );\r
-global ASM_PFX(XenHypercall2)\r
-ASM_PFX(XenHypercall2):\r
+global ASM_PFX(__XenHypercall2)\r
+ASM_PFX(__XenHypercall2):\r
   push rdi\r
   push rsi\r
   ; Copy HypercallAddr to rax\r
index 7a7fd82d559d1a1604d8b4fa4ddc82798c72840d..d333b331b6db72b94e9d9663b706139d0bc1a8d0 100644 (file)
@@ -34,6 +34,8 @@
 #include "XenStore.h"\r
 #include "XenBus.h"\r
 \r
+#include <IndustryStandard/Xen/hvm/params.h>\r
+#include <IndustryStandard/Xen/memory.h>\r
 \r
 ///\r
 /// Driver Binding Protocol instance\r
@@ -51,6 +53,46 @@ EFI_DRIVER_BINDING_PROTOCOL gXenBusDxeDriverBinding = {
 STATIC EFI_LOCK       mMyDeviceLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_CALLBACK);\r
 STATIC XENBUS_DEVICE *mMyDevice = NULL;\r
 \r
+/**\r
+  Map the shared_info_t page into memory.\r
+\r
+  @param Dev    A XENBUS_DEVICE instance.\r
+\r
+  @retval EFI_SUCCESS     Dev->SharedInfo whill contain a pointer to\r
+                          the shared info page\r
+  @retval EFI_LOAD_ERROR  The shared info page could not be mapped. The\r
+                          hypercall returned an error.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+XenGetSharedInfoPage (\r
+  IN OUT XENBUS_DEVICE *Dev\r
+  )\r
+{\r
+  xen_add_to_physmap_t Parameter;\r
+\r
+  ASSERT (Dev->SharedInfo == NULL);\r
+\r
+  Parameter.domid = DOMID_SELF;\r
+  Parameter.space = XENMAPSPACE_shared_info;\r
+  Parameter.idx = 0;\r
+\r
+  //\r
+  // using reserved page because the page is not released when Linux is\r
+  // starting because of the add_to_physmap. QEMU might try to access the\r
+  // page, and fail because it have no right to do so (segv).\r
+  //\r
+  Dev->SharedInfo = AllocateReservedPages (1);\r
+  Parameter.gpfn = (UINTN) Dev->SharedInfo >> EFI_PAGE_SHIFT;\r
+  if (XenHypercallMemoryOp (XENMEM_add_to_physmap, &Parameter) != 0) {\r
+    FreePages (Dev->SharedInfo, 1);\r
+    Dev->SharedInfo = NULL;\r
+    return EFI_LOAD_ERROR;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Unloads an image.\r
 \r
@@ -348,7 +390,7 @@ XenBusDxeDriverBindingStart (
   MmioAddr = BarDesc->AddrRangeMin;\r
   FreePool (BarDesc);\r
 \r
-  Status = XenHyperpageInit (Dev);\r
+  Status = XenHyperpageInit ();\r
   if (EFI_ERROR (Status)) {\r
     DEBUG ((EFI_D_ERROR, "XenBus: Unable to retrieve the hyperpage.\n"));\r
     Status = EFI_UNSUPPORTED;\r
index 80253b7d1ca9e446ed40221322384276c4cd4714..9b7219906a69f19788469816f46cc800c40f9c90 100644 (file)
@@ -91,7 +91,6 @@ struct _XENBUS_DEVICE {
   EFI_DEVICE_PATH_PROTOCOL      *DevicePath;\r
   LIST_ENTRY                    ChildList;\r
 \r
-  VOID                          *Hyperpage;\r
   shared_info_t                 *SharedInfo;\r
 };\r
 \r
index 34d92e76b7e38d24d670be41d3da12e963cbeda7..e7134fcf74cea4fcf751b5f6300baaa1bad11e93 100644 (file)
 #include <IndustryStandard/Xen/hvm/params.h>\r
 #include <IndustryStandard/Xen/memory.h>\r
 \r
+STATIC VOID       *HyperPage;\r
+\r
+//\r
+// Interface exposed by the ASM implementation of the core hypercall\r
+//\r
+INTN\r
+EFIAPI\r
+__XenHypercall2 (\r
+  IN     VOID *HypercallAddr,\r
+  IN OUT INTN Arg1,\r
+  IN OUT INTN Arg2\r
+  );\r
+\r
 EFI_STATUS\r
 XenHyperpageInit (\r
-  IN OUT XENBUS_DEVICE *Dev\r
   )\r
 {\r
   EFI_HOB_GUID_TYPE   *GuidHob;\r
@@ -36,24 +48,21 @@ XenHyperpageInit (
     return EFI_NOT_FOUND;\r
   }\r
   XenInfo = (EFI_XEN_INFO *) GET_GUID_HOB_DATA (GuidHob);\r
-  Dev->Hyperpage = XenInfo->HyperPages;\r
+  HyperPage = XenInfo->HyperPages;\r
   return EFI_SUCCESS;\r
 }\r
 \r
 UINT64\r
 XenHypercallHvmGetParam (\r
-  IN XENBUS_DEVICE *Dev,\r
   IN UINT32        Index\r
   )\r
 {\r
   xen_hvm_param_t     Parameter;\r
   INTN                Error;\r
 \r
-  ASSERT (Dev->Hyperpage != NULL);\r
-\r
   Parameter.domid = DOMID_SELF;\r
   Parameter.index = Index;\r
-  Error = XenHypercall2 ((UINT8*)Dev->Hyperpage + __HYPERVISOR_hvm_op * 32,\r
+  Error = XenHypercall2 (__HYPERVISOR_hvm_op,\r
                          HVMOP_get_param, (INTN) &Parameter);\r
   if (Error != 0) {\r
     DEBUG ((EFI_D_ERROR,\r
@@ -66,53 +75,33 @@ XenHypercallHvmGetParam (
 \r
 INTN\r
 XenHypercallMemoryOp (\r
-  IN     XENBUS_DEVICE *Dev,\r
   IN     UINTN Operation,\r
   IN OUT VOID *Arguments\r
   )\r
 {\r
-  ASSERT (Dev->Hyperpage != NULL);\r
-  return XenHypercall2 ((UINT8*)Dev->Hyperpage + __HYPERVISOR_memory_op * 32,\r
+  return XenHypercall2 (__HYPERVISOR_memory_op,\r
                         Operation, (INTN) Arguments);\r
 }\r
 \r
 INTN\r
 XenHypercallEventChannelOp (\r
-  IN     XENBUS_DEVICE *Dev,\r
   IN     INTN Operation,\r
   IN OUT VOID *Arguments\r
   )\r
 {\r
-  ASSERT (Dev->Hyperpage != NULL);\r
-  return XenHypercall2 ((UINT8*)Dev->Hyperpage + __HYPERVISOR_event_channel_op * 32,\r
+  return XenHypercall2 (__HYPERVISOR_event_channel_op,\r
                         Operation, (INTN) Arguments);\r
 }\r
 \r
-EFI_STATUS\r
-XenGetSharedInfoPage (\r
-  IN OUT XENBUS_DEVICE *Dev\r
+INTN\r
+EFIAPI\r
+XenHypercall2 (\r
+  IN     UINTN  HypercallID,\r
+  IN OUT INTN   Arg1,\r
+  IN OUT INTN   Arg2\r
   )\r
 {\r
-  xen_add_to_physmap_t Parameter;\r
+  ASSERT (HyperPage != NULL);\r
 \r
-  ASSERT (Dev->SharedInfo == NULL);\r
-\r
-  Parameter.domid = DOMID_SELF;\r
-  Parameter.space = XENMAPSPACE_shared_info;\r
-  Parameter.idx = 0;\r
-\r
-  //\r
-  // using reserved page because the page is not released when Linux is\r
-  // starting because of the add_to_physmap. QEMU might try to access the\r
-  // page, and fail because it have no right to do so (segv).\r
-  //\r
-  Dev->SharedInfo = AllocateReservedPages (1);\r
-  Parameter.gpfn = (UINTN) Dev->SharedInfo >> EFI_PAGE_SHIFT;\r
-  if (XenHypercallMemoryOp (Dev, XENMEM_add_to_physmap, &Parameter) != 0) {\r
-    FreePages (Dev->SharedInfo, 1);\r
-    Dev->SharedInfo = NULL;\r
-    return EFI_LOAD_ERROR;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
+  return __XenHypercall2 ((UINT8*)HyperPage + HypercallID * 32, Arg1, Arg2);\r
 }\r
index 06693830e16e01858a5cd3464e4f85eaff0ef842..9d49e33eb5af556158eed549b528ff5558966d14 100644 (file)
@@ -18,9 +18,9 @@
 \r
 /**\r
   This function will put the two arguments in the right place (registers) and\r
-  call HypercallAddr, which correspond to an entry in the hypercall pages.\r
+  invoke the hypercall identified by HypercallID.\r
 \r
-  @param HypercallAddr  A memory address where the hypercall to call is.\r
+  @param HypercallID    The symbolic ID of the hypercall to be invoked\r
   @param Arg1           First argument.\r
   @param Arg2           Second argument.\r
 \r
@@ -29,7 +29,7 @@
 INTN\r
 EFIAPI\r
 XenHypercall2 (\r
-  IN     VOID *HypercallAddr,\r
+  IN     INTN HypercallID,\r
   IN OUT INTN Arg1,\r
   IN OUT INTN Arg2\r
   );\r
@@ -44,27 +44,23 @@ XenHypercall2 (
 **/\r
 EFI_STATUS\r
 XenHyperpageInit (\r
-  XENBUS_DEVICE *Dev\r
   );\r
 \r
 /**\r
   Return the value of the HVM parameter Index.\r
 \r
-  @param Dev    A XENBUS_DEVICE instance.\r
   @param Index  The parameter to get, e.g. HVM_PARAM_STORE_EVTCHN.\r
 \r
   @return   The value of the asked parameter or 0 in case of error.\r
 **/\r
 UINT64\r
 XenHypercallHvmGetParam (\r
-  XENBUS_DEVICE *Dev,\r
   UINT32 Index\r
   );\r
 \r
 /**\r
   Hypercall to do different operation on the memory.\r
 \r
-  @param Dev        A XENBUS_DEVICE instance.\r
   @param Operation  The operation number, e.g. XENMEM_add_to_physmap.\r
   @param Arguments  The arguments associated to the operation.\r
 \r
@@ -73,7 +69,6 @@ XenHypercallHvmGetParam (
 **/\r
 INTN\r
 XenHypercallMemoryOp (\r
-  IN     XENBUS_DEVICE *Dev,\r
   IN     UINTN Operation,\r
   IN OUT VOID *Arguments\r
   );\r
@@ -81,7 +76,6 @@ XenHypercallMemoryOp (
 /**\r
   Do an operation on the event channels.\r
 \r
-  @param Dev        A XENBUS_DEVICE instance.\r
   @param Operation  The operation number, e.g. EVTCHNOP_send.\r
   @param Arguments  The argument associated to the operation.\r
 \r
@@ -90,24 +84,8 @@ XenHypercallMemoryOp (
 **/\r
 INTN\r
 XenHypercallEventChannelOp (\r
-  IN     XENBUS_DEVICE *Dev,\r
   IN     INTN Operation,\r
   IN OUT VOID *Arguments\r
   );\r
 \r
-/**\r
-  Map the shared_info_t page into memory.\r
-\r
-  @param Dev    A XENBUS_DEVICE instance.\r
-\r
-  @retval EFI_SUCCESS     Dev->SharedInfo whill contain a pointer to\r
-                          the shared info page\r
-  @retval EFI_LOAD_ERROR  The shared info page could not be mapped. The\r
-                          hypercall returned an error.\r
-**/\r
-EFI_STATUS\r
-XenGetSharedInfoPage (\r
-  IN OUT XENBUS_DEVICE *Dev\r
-  );\r
-\r
 #endif\r
index 2df8f534858518d4174949115fb1492fb0335a33..7ec1e634bc5c16e6e76a324bb7645327f17a4c65 100644 (file)
@@ -1057,8 +1057,8 @@ XenStoreInit (
 \r
   xs.Dev = Dev;\r
 \r
-  xs.EventChannel = (evtchn_port_t)XenHypercallHvmGetParam (Dev, HVM_PARAM_STORE_EVTCHN);\r
-  XenStoreGpfn = (UINTN)XenHypercallHvmGetParam (Dev, HVM_PARAM_STORE_PFN);\r
+  xs.EventChannel = (evtchn_port_t)XenHypercallHvmGetParam (HVM_PARAM_STORE_EVTCHN);\r
+  XenStoreGpfn = (UINTN)XenHypercallHvmGetParam (HVM_PARAM_STORE_PFN);\r
   xs.XenStore = (VOID *) (XenStoreGpfn << EFI_PAGE_SHIFT);\r
   DEBUG ((EFI_D_INFO, "XenBusInit: XenBus rings @%p, event channel %x\n",\r
           xs.XenStore, xs.EventChannel));\r