diff --git a/OvmfPkg/Include/Protocol/XenBus.h b/OvmfPkg/Include/Protocol/XenBus.h index 8d1fb52c22..4c1247bc93 100644 --- a/OvmfPkg/Include/Protocol/XenBus.h +++ b/OvmfPkg/Include/Protocol/XenBus.h @@ -63,6 +63,7 @@ typedef enum { #include +#include /// /// Function prototypes @@ -249,6 +250,54 @@ EFI_STATUS IN grant_ref_t Ref ); +/** + Allocate a port that can be bind from domain DomainId. + + @param This A pointer to the XENBUS_PROTOCOL. + @param DomainId The domain ID that can bind the newly allocated port. + @param Port A pointer to a evtchn_port_t that will contain the newly + allocated port. + + @retval UINT32 The return value from the hypercall, 0 if success. +**/ +typedef +UINT32 +(EFIAPI *XENBUS_EVENT_CHANNEL_ALLOCATE) ( + IN XENBUS_PROTOCOL *This, + IN domid_t DomainId, + OUT evtchn_port_t *Port + ); + +/** + Send an event to the remote end of the channel whose local endpoint is Port. + + @param This A pointer to the XENBUS_PROTOCOL. + @param Port Local port to the the event from. + + @retval UINT32 The return value from the hypercall, 0 if success. +**/ +typedef +UINT32 +(EFIAPI *XENBUS_EVENT_CHANNEL_NOTIFY) ( + IN XENBUS_PROTOCOL *This, + IN evtchn_port_t Port + ); + +/** + Close a local event channel Port. + + @param This A pointer to the XENBUS_PROTOCOL. + @param Port The event channel to close. + + @retval UINT32 The return value from the hypercall, 0 if success. +**/ +typedef +UINT32 +(EFIAPI *XENBUS_EVENT_CHANNEL_CLOSE) ( + IN XENBUS_PROTOCOL *This, + IN evtchn_port_t Port + ); + /** Register a XenStore watch. @@ -345,6 +394,10 @@ struct _XENBUS_PROTOCOL { XENBUS_GRANT_ACCESS GrantAccess; XENBUS_GRANT_END_ACCESS GrantEndAccess; + XENBUS_EVENT_CHANNEL_ALLOCATE EventChannelAllocate; + XENBUS_EVENT_CHANNEL_NOTIFY EventChannelNotify; + XENBUS_EVENT_CHANNEL_CLOSE EventChannelClose; + XENBUS_REGISTER_WATCH RegisterWatch; XENBUS_REGISTER_WATCH_BACKEND RegisterWatchBackend; XENBUS_UNREGISTER_WATCH UnregisterWatch; diff --git a/OvmfPkg/XenBusDxe/EventChannel.c b/OvmfPkg/XenBusDxe/EventChannel.c index c4076c49ea..547c111aae 100644 --- a/OvmfPkg/XenBusDxe/EventChannel.c +++ b/OvmfPkg/XenBusDxe/EventChannel.c @@ -31,3 +31,58 @@ XenEventChannelNotify ( ReturnCode = XenHypercallEventChannelOp (Dev, EVTCHNOP_send, &Send); return ReturnCode; } + +UINT32 +EFIAPI +XenBusEventChannelAllocate ( + IN XENBUS_PROTOCOL *This, + IN domid_t DomainId, + 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 = XenHypercallEventChannelOp (Private->Dev, + EVTCHNOP_alloc_unbound, + &Parameter); + if (ReturnCode != 0) { + DEBUG ((EFI_D_ERROR, "ERROR: alloc_unbound failed with rc=%d", ReturnCode)); + return ReturnCode; + } + *Port = Parameter.port; + return ReturnCode; +} + +UINT32 +EFIAPI +XenBusEventChannelNotify ( + IN XENBUS_PROTOCOL *This, + IN evtchn_port_t Port + ) +{ + XENBUS_PRIVATE_DATA *Private; + + Private = XENBUS_PRIVATE_DATA_FROM_THIS(This); + return XenEventChannelNotify (Private->Dev, Port); +} + +UINT32 +EFIAPI +XenBusEventChannelClose ( + IN XENBUS_PROTOCOL *This, + IN evtchn_port_t Port + ) +{ + XENBUS_PRIVATE_DATA *Private; + evtchn_close_t Close; + + Private = XENBUS_PRIVATE_DATA_FROM_THIS (This); + Close.port = Port; + return XenHypercallEventChannelOp (Private->Dev, EVTCHNOP_close, &Close); +} diff --git a/OvmfPkg/XenBusDxe/EventChannel.h b/OvmfPkg/XenBusDxe/EventChannel.h index 5f3171d7ca..4dcc20f73b 100644 --- a/OvmfPkg/XenBusDxe/EventChannel.h +++ b/OvmfPkg/XenBusDxe/EventChannel.h @@ -33,4 +33,56 @@ XenEventChannelNotify ( IN evtchn_port_t Port ); +/* + * XenBus protocol + */ + +/** + Allocate a port that can be bind from domain DomainId. + + @param This A pointer to the XENBUS_PROTOCOL. + @param DomainId The domain ID that can bind the newly allocated port. + @param Port A pointer to a evtchn_port_t that will contain the newly + allocated port. + + @retval UINT32 The return value from the hypercall, 0 if success. +**/ +UINT32 +EFIAPI +XenBusEventChannelAllocate ( + IN XENBUS_PROTOCOL *This, + IN domid_t DomainId, + OUT evtchn_port_t *Port + ); + +/** + Send an event to the remote end of the channel whose local endpoint is Port. + + @param This A pointer to the XENBUS_PROTOCOL. + @param Port Local port to the the event from. + + @retval UINT32 The return value from the hypercall, 0 if success. +**/ +UINT32 +EFIAPI +XenBusEventChannelNotify ( + IN XENBUS_PROTOCOL *This, + IN evtchn_port_t Port + ); + +/** + Close a local event channel Port. + + @param This A pointer to the XENBUS_PROTOCOL. + @param Port The event channel to close. + + @retval UINT32 The return value from the hypercall, 0 if success. +**/ +UINT32 +EFIAPI +XenBusEventChannelClose ( + IN XENBUS_PROTOCOL *This, + IN evtchn_port_t Port + ); + #endif diff --git a/OvmfPkg/XenBusDxe/XenBus.c b/OvmfPkg/XenBusDxe/XenBus.c index edd2d95217..896a6607b7 100644 --- a/OvmfPkg/XenBusDxe/XenBus.c +++ b/OvmfPkg/XenBusDxe/XenBus.c @@ -359,6 +359,9 @@ STATIC XENBUS_PRIVATE_DATA gXenBusPrivateData = { .XenBusIo.SetState = XenBusSetState, .XenBusIo.GrantAccess = XenBusGrantAccess, .XenBusIo.GrantEndAccess = XenBusGrantEndAccess, + .XenBusIo.EventChannelAllocate = XenBusEventChannelAllocate, + .XenBusIo.EventChannelNotify = XenBusEventChannelNotify, + .XenBusIo.EventChannelClose = XenBusEventChannelClose, .XenBusIo.RegisterWatch = XenBusRegisterWatch, .XenBusIo.RegisterWatchBackend = XenBusRegisterWatchBackend, .XenBusIo.UnregisterWatch = XenBusUnregisterWatch,