mirror of
				https://github.com/qemu/qemu.git
				synced 2025-10-31 04:06:46 +00:00 
			
		
		
		
	 c4583c8c39
			
		
	
	
		c4583c8c39
		
	
	
	
	
		
			
			Currently a single watch on /local/domain/X/backend is registered by each QEMU process running in service domain X (where X is usually 0). The purpose of this watch is to ensure that QEMU is notified when the Xen toolstack creates a new device backend area. Such a backend area is specific to a single frontend area created for a specific guest domain and, since each QEMU process is also created to service a specfic guest domain, it is unnecessary and inefficient to notify all QEMU processes. Only the QEMU process associated with the same guest domain need receive the notification. This patch re-factors the watch registration code such that notifications are targetted appropriately. Reported-by: Jerome Leseinne <jerome.leseinne@gmail.com> Signed-off-by: Paul Durrant <pdurrant@amazon.com> Reviewed-by: Anthony PERARD <anthony.perard@citrix.com> Message-Id: <20201001081500.1026-1-paul@xen.org> Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
		
			
				
	
	
		
			140 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2018  Citrix Systems Inc.
 | |
|  *
 | |
|  * This work is licensed under the terms of the GNU GPL, version 2 or later.
 | |
|  * See the COPYING file in the top-level directory.
 | |
|  */
 | |
| 
 | |
| #ifndef HW_XEN_BUS_H
 | |
| #define HW_XEN_BUS_H
 | |
| 
 | |
| #include "hw/xen/xen_common.h"
 | |
| #include "hw/sysbus.h"
 | |
| #include "qemu/notify.h"
 | |
| #include "qom/object.h"
 | |
| 
 | |
| typedef void (*XenWatchHandler)(void *opaque);
 | |
| 
 | |
| typedef struct XenWatchList XenWatchList;
 | |
| typedef struct XenWatch XenWatch;
 | |
| typedef struct XenEventChannel XenEventChannel;
 | |
| 
 | |
| struct XenDevice {
 | |
|     DeviceState qdev;
 | |
|     domid_t frontend_id;
 | |
|     char *name;
 | |
|     struct xs_handle *xsh;
 | |
|     XenWatchList *watch_list;
 | |
|     char *backend_path, *frontend_path;
 | |
|     enum xenbus_state backend_state, frontend_state;
 | |
|     Notifier exit;
 | |
|     XenWatch *backend_state_watch, *frontend_state_watch;
 | |
|     bool backend_online;
 | |
|     XenWatch *backend_online_watch;
 | |
|     xengnttab_handle *xgth;
 | |
|     bool feature_grant_copy;
 | |
|     bool inactive;
 | |
|     QLIST_HEAD(, XenEventChannel) event_channels;
 | |
|     QLIST_ENTRY(XenDevice) list;
 | |
| };
 | |
| typedef struct XenDevice XenDevice;
 | |
| 
 | |
| typedef char *(*XenDeviceGetName)(XenDevice *xendev, Error **errp);
 | |
| typedef void (*XenDeviceRealize)(XenDevice *xendev, Error **errp);
 | |
| typedef void (*XenDeviceFrontendChanged)(XenDevice *xendev,
 | |
|                                          enum xenbus_state frontend_state,
 | |
|                                          Error **errp);
 | |
| typedef void (*XenDeviceUnrealize)(XenDevice *xendev);
 | |
| 
 | |
| struct XenDeviceClass {
 | |
|     /*< private >*/
 | |
|     DeviceClass parent_class;
 | |
|     /*< public >*/
 | |
|     const char *backend;
 | |
|     const char *device;
 | |
|     XenDeviceGetName get_name;
 | |
|     XenDeviceRealize realize;
 | |
|     XenDeviceFrontendChanged frontend_changed;
 | |
|     XenDeviceUnrealize unrealize;
 | |
| };
 | |
| 
 | |
| #define TYPE_XEN_DEVICE "xen-device"
 | |
| OBJECT_DECLARE_TYPE(XenDevice, XenDeviceClass, XEN_DEVICE)
 | |
| 
 | |
| struct XenBus {
 | |
|     BusState qbus;
 | |
|     domid_t backend_id;
 | |
|     struct xs_handle *xsh;
 | |
|     XenWatchList *watch_list;
 | |
|     unsigned int backend_types;
 | |
|     XenWatch **backend_watch;
 | |
|     QLIST_HEAD(, XenDevice) inactive_devices;
 | |
| };
 | |
| 
 | |
| struct XenBusClass {
 | |
|     /*< private >*/
 | |
|     BusClass parent_class;
 | |
| };
 | |
| 
 | |
| #define TYPE_XEN_BUS "xen-bus"
 | |
| OBJECT_DECLARE_TYPE(XenBus, XenBusClass,
 | |
|                     XEN_BUS)
 | |
| 
 | |
| void xen_bus_init(void);
 | |
| 
 | |
| void xen_device_backend_set_state(XenDevice *xendev,
 | |
|                                   enum xenbus_state state);
 | |
| enum xenbus_state xen_device_backend_get_state(XenDevice *xendev);
 | |
| 
 | |
| void xen_device_backend_printf(XenDevice *xendev, const char *key,
 | |
|                                const char *fmt, ...)
 | |
|     GCC_FMT_ATTR(3, 4);
 | |
| void xen_device_frontend_printf(XenDevice *xendev, const char *key,
 | |
|                                 const char *fmt, ...)
 | |
|     GCC_FMT_ATTR(3, 4);
 | |
| 
 | |
| int xen_device_frontend_scanf(XenDevice *xendev, const char *key,
 | |
|                               const char *fmt, ...);
 | |
| 
 | |
| void xen_device_set_max_grant_refs(XenDevice *xendev, unsigned int nr_refs,
 | |
|                                    Error **errp);
 | |
| void *xen_device_map_grant_refs(XenDevice *xendev, uint32_t *refs,
 | |
|                                 unsigned int nr_refs, int prot,
 | |
|                                 Error **errp);
 | |
| void xen_device_unmap_grant_refs(XenDevice *xendev, void *map,
 | |
|                                  unsigned int nr_refs, Error **errp);
 | |
| 
 | |
| typedef struct XenDeviceGrantCopySegment {
 | |
|     union {
 | |
|         void *virt;
 | |
|         struct {
 | |
|             uint32_t ref;
 | |
|             off_t offset;
 | |
|         } foreign;
 | |
|     } source, dest;
 | |
|     size_t len;
 | |
| } XenDeviceGrantCopySegment;
 | |
| 
 | |
| void xen_device_copy_grant_refs(XenDevice *xendev, bool to_domain,
 | |
|                                 XenDeviceGrantCopySegment segs[],
 | |
|                                 unsigned int nr_segs, Error **errp);
 | |
| 
 | |
| typedef bool (*XenEventHandler)(void *opaque);
 | |
| 
 | |
| XenEventChannel *xen_device_bind_event_channel(XenDevice *xendev,
 | |
|                                                unsigned int port,
 | |
|                                                XenEventHandler handler,
 | |
|                                                void *opaque, Error **errp);
 | |
| void xen_device_set_event_channel_context(XenDevice *xendev,
 | |
|                                           XenEventChannel *channel,
 | |
|                                           AioContext *ctx,
 | |
|                                           Error **errp);
 | |
| void xen_device_notify_event_channel(XenDevice *xendev,
 | |
|                                      XenEventChannel *channel,
 | |
|                                      Error **errp);
 | |
| void xen_device_unbind_event_channel(XenDevice *xendev,
 | |
|                                      XenEventChannel *channel,
 | |
|                                      Error **errp);
 | |
| 
 | |
| #endif /* HW_XEN_BUS_H */
 |