| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  xen backend driver infrastructure | 
					
						
							|  |  |  |  *  (c) 2008 Gerd Hoffmann <kraxel@redhat.com> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  *  it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |  *  the Free Software Foundation; under version 2 of the License. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  *  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  *  GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  You should have received a copy of the GNU General Public License along | 
					
						
							| 
									
										
										
										
											2009-07-16 20:47:01 +00:00
										 |  |  |  *  with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2012-01-13 17:44:23 +01:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  Contributions after 2012-01-13 are licensed under the terms of the | 
					
						
							|  |  |  |  *  GNU GPL, version 2 or (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * TODO: add some xenbus / xenstore concepts overview here. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 18:17:06 +00:00
										 |  |  | #include "qemu/osdep.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-13 11:12:21 +02:00
										 |  |  | #include "hw/sysbus.h"
 | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  | #include "hw/boards.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:51 +02:00
										 |  |  | #include "hw/qdev-properties.h"
 | 
					
						
							| 
									
										
										
										
											2012-12-17 18:20:00 +01:00
										 |  |  | #include "qemu/log.h"
 | 
					
						
							| 
									
										
										
											
												Include qemu/main-loop.h less
In my "build everything" tree, changing qemu/main-loop.h triggers a
recompile of some 5600 out of 6600 objects (not counting tests and
objects that don't depend on qemu/osdep.h).  It includes block/aio.h,
which in turn includes qemu/event_notifier.h, qemu/notify.h,
qemu/processor.h, qemu/qsp.h, qemu/queue.h, qemu/thread-posix.h,
qemu/thread.h, qemu/timer.h, and a few more.
Include qemu/main-loop.h only where it's needed.  Touching it now
recompiles only some 1700 objects.  For block/aio.h and
qemu/event_notifier.h, these numbers drop from 5600 to 2800.  For the
others, they shrink only slightly.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20190812052359.30071-21-armbru@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
											
										 
											2019-08-12 07:23:50 +02:00
										 |  |  | #include "qemu/main-loop.h"
 | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:56 +01:00
										 |  |  | #include "qapi/error.h"
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | #include "hw/xen/xen-legacy-backend.h"
 | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:09 +03:00
										 |  |  | #include "hw/xen/xen_pvdev.h"
 | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  | #include "monitor/qdev.h"
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-13 11:12:21 +02:00
										 |  |  | DeviceState *xen_sysdev; | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:56 +01:00
										 |  |  | BusState *xen_sysbus; | 
					
						
							| 
									
										
										
										
											2016-06-13 11:12:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | /* ------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* public */ | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | struct xs_handle *xenstore; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:39 +00:00
										 |  |  | const char *xen_protocol; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* private */ | 
					
						
							| 
									
										
										
										
											2018-05-17 16:35:56 +01:00
										 |  |  | static bool xen_feature_grant_copy; | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:07 +03:00
										 |  |  | static int debug; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | int xenstore_write_be_str(struct XenLegacyDevice *xendev, const char *node, | 
					
						
							|  |  |  |                           const char *val) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     return xenstore_write_str(xendev->be, node, val); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | int xenstore_write_be_int(struct XenLegacyDevice *xendev, const char *node, | 
					
						
							|  |  |  |                           int ival) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     return xenstore_write_int(xendev->be, node, ival); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | int xenstore_write_be_int64(struct XenLegacyDevice *xendev, const char *node, | 
					
						
							|  |  |  |                             int64_t ival) | 
					
						
							| 
									
										
										
										
											2013-04-05 15:37:32 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     return xenstore_write_int64(xendev->be, node, ival); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | char *xenstore_read_be_str(struct XenLegacyDevice *xendev, const char *node) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     return xenstore_read_str(xendev->be, node); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | int xenstore_read_be_int(struct XenLegacyDevice *xendev, const char *node, | 
					
						
							|  |  |  |                          int *ival) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     return xenstore_read_int(xendev->be, node, ival); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | char *xenstore_read_fe_str(struct XenLegacyDevice *xendev, const char *node) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     return xenstore_read_str(xendev->fe, node); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | int xenstore_read_fe_int(struct XenLegacyDevice *xendev, const char *node, | 
					
						
							|  |  |  |                          int *ival) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     return xenstore_read_int(xendev->fe, node, ival); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | int xenstore_read_fe_uint64(struct XenLegacyDevice *xendev, const char *node, | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:08 +03:00
										 |  |  |                             uint64_t *uval) | 
					
						
							| 
									
										
										
										
											2013-12-18 19:17:31 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     return xenstore_read_uint64(xendev->fe, node, uval); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | /* ------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | int xen_be_set_state(struct XenLegacyDevice *xendev, enum xenbus_state state) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int rc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rc = xenstore_write_be_int(xendev, "state", state); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     if (rc < 0) { | 
					
						
							|  |  |  |         return rc; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |     xen_pv_printf(xendev, 1, "backend state: %s -> %s\n", | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |                   xenbus_strstate(xendev->be_state), xenbus_strstate(state)); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     xendev->be_state = state; | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | void xen_be_set_max_grant_refs(struct XenLegacyDevice *xendev, | 
					
						
							| 
									
										
										
										
											2018-05-17 16:35:51 +01:00
										 |  |  |                                unsigned int nr_refs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (xengnttab_set_max_grants(xendev->gnttabdev, nr_refs)) { | 
					
						
							|  |  |  |         xen_pv_printf(xendev, 0, "xengnttab_set_max_grants failed: %s\n", | 
					
						
							|  |  |  |                       strerror(errno)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | void *xen_be_map_grant_refs(struct XenLegacyDevice *xendev, uint32_t *refs, | 
					
						
							| 
									
										
										
										
											2018-05-17 16:35:51 +01:00
										 |  |  |                             unsigned int nr_refs, int prot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     void *ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ptr = xengnttab_map_domain_grant_refs(xendev->gnttabdev, nr_refs, | 
					
						
							|  |  |  |                                           xen_domid, refs, prot); | 
					
						
							|  |  |  |     if (!ptr) { | 
					
						
							|  |  |  |         xen_pv_printf(xendev, 0, | 
					
						
							|  |  |  |                       "xengnttab_map_domain_grant_refs failed: %s\n", | 
					
						
							|  |  |  |                       strerror(errno)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | void xen_be_unmap_grant_refs(struct XenLegacyDevice *xendev, void *ptr, | 
					
						
							| 
									
										
										
										
											2018-05-17 16:35:51 +01:00
										 |  |  |                              unsigned int nr_refs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (xengnttab_unmap(xendev->gnttabdev, ptr, nr_refs)) { | 
					
						
							|  |  |  |         xen_pv_printf(xendev, 0, "xengnttab_unmap failed: %s\n", | 
					
						
							|  |  |  |                       strerror(errno)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | static int compat_copy_grant_refs(struct XenLegacyDevice *xendev, | 
					
						
							| 
									
										
										
										
											2018-05-17 16:35:54 +01:00
										 |  |  |                                   bool to_domain, | 
					
						
							|  |  |  |                                   XenGrantCopySegment segs[], | 
					
						
							|  |  |  |                                   unsigned int nr_segs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uint32_t *refs = g_new(uint32_t, nr_segs); | 
					
						
							|  |  |  |     int prot = to_domain ? PROT_WRITE : PROT_READ; | 
					
						
							|  |  |  |     void *pages; | 
					
						
							|  |  |  |     unsigned int i; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < nr_segs; i++) { | 
					
						
							|  |  |  |         XenGrantCopySegment *seg = &segs[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         refs[i] = to_domain ? | 
					
						
							|  |  |  |             seg->dest.foreign.ref : seg->source.foreign.ref; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     pages = xengnttab_map_domain_grant_refs(xendev->gnttabdev, nr_segs, | 
					
						
							|  |  |  |                                             xen_domid, refs, prot); | 
					
						
							|  |  |  |     if (!pages) { | 
					
						
							|  |  |  |         xen_pv_printf(xendev, 0, | 
					
						
							|  |  |  |                       "xengnttab_map_domain_grant_refs failed: %s\n", | 
					
						
							|  |  |  |                       strerror(errno)); | 
					
						
							|  |  |  |         g_free(refs); | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < nr_segs; i++) { | 
					
						
							|  |  |  |         XenGrantCopySegment *seg = &segs[i]; | 
					
						
							|  |  |  |         void *page = pages + (i * XC_PAGE_SIZE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (to_domain) { | 
					
						
							|  |  |  |             memcpy(page + seg->dest.foreign.offset, seg->source.virt, | 
					
						
							|  |  |  |                    seg->len); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             memcpy(seg->dest.virt, page + seg->source.foreign.offset, | 
					
						
							|  |  |  |                    seg->len); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (xengnttab_unmap(xendev->gnttabdev, pages, nr_segs)) { | 
					
						
							|  |  |  |         xen_pv_printf(xendev, 0, "xengnttab_unmap failed: %s\n", | 
					
						
							|  |  |  |                       strerror(errno)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     g_free(refs); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | int xen_be_copy_grant_refs(struct XenLegacyDevice *xendev, | 
					
						
							| 
									
										
										
										
											2018-05-17 16:35:51 +01:00
										 |  |  |                            bool to_domain, | 
					
						
							|  |  |  |                            XenGrantCopySegment segs[], | 
					
						
							|  |  |  |                            unsigned int nr_segs) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     xengnttab_grant_copy_segment_t *xengnttab_segs; | 
					
						
							|  |  |  |     unsigned int i; | 
					
						
							|  |  |  |     int rc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert(xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-17 16:35:54 +01:00
										 |  |  |     if (!xen_feature_grant_copy) { | 
					
						
							|  |  |  |         return compat_copy_grant_refs(xendev, to_domain, segs, nr_segs); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-17 16:35:51 +01:00
										 |  |  |     xengnttab_segs = g_new0(xengnttab_grant_copy_segment_t, nr_segs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < nr_segs; i++) { | 
					
						
							|  |  |  |         XenGrantCopySegment *seg = &segs[i]; | 
					
						
							|  |  |  |         xengnttab_grant_copy_segment_t *xengnttab_seg = &xengnttab_segs[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (to_domain) { | 
					
						
							|  |  |  |             xengnttab_seg->flags = GNTCOPY_dest_gref; | 
					
						
							|  |  |  |             xengnttab_seg->dest.foreign.domid = xen_domid; | 
					
						
							|  |  |  |             xengnttab_seg->dest.foreign.ref = seg->dest.foreign.ref; | 
					
						
							|  |  |  |             xengnttab_seg->dest.foreign.offset = seg->dest.foreign.offset; | 
					
						
							|  |  |  |             xengnttab_seg->source.virt = seg->source.virt; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             xengnttab_seg->flags = GNTCOPY_source_gref; | 
					
						
							|  |  |  |             xengnttab_seg->source.foreign.domid = xen_domid; | 
					
						
							|  |  |  |             xengnttab_seg->source.foreign.ref = seg->source.foreign.ref; | 
					
						
							|  |  |  |             xengnttab_seg->source.foreign.offset = | 
					
						
							|  |  |  |                 seg->source.foreign.offset; | 
					
						
							|  |  |  |             xengnttab_seg->dest.virt = seg->dest.virt; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         xengnttab_seg->len = seg->len; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     rc = xengnttab_grant_copy(xendev->gnttabdev, nr_segs, xengnttab_segs); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (rc) { | 
					
						
							|  |  |  |         xen_pv_printf(xendev, 0, "xengnttab_copy failed: %s\n", | 
					
						
							|  |  |  |                       strerror(errno)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (i = 0; i < nr_segs; i++) { | 
					
						
							|  |  |  |         xengnttab_grant_copy_segment_t *xengnttab_seg = | 
					
						
							|  |  |  |             &xengnttab_segs[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (xengnttab_seg->status != GNTST_okay) { | 
					
						
							|  |  |  |             xen_pv_printf(xendev, 0, "segment[%u] status: %d\n", i, | 
					
						
							|  |  |  |                           xengnttab_seg->status); | 
					
						
							|  |  |  |             rc = -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     g_free(xengnttab_segs); | 
					
						
							|  |  |  |     return rc; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * get xen backend device, allocate a new one if it doesn't exist. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | static struct XenLegacyDevice *xen_be_get_xendev(const char *type, int dom, | 
					
						
							|  |  |  |                                                  int dev, | 
					
						
							|  |  |  |                                                  struct XenDevOps *ops) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  |     struct XenLegacyDevice *xendev; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:18 +03:00
										 |  |  |     xendev = xen_pv_find_xendev(type, dom, dev); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     if (xendev) { | 
					
						
							|  |  |  |         return xendev; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* init new xendev */ | 
					
						
							| 
									
										
										
										
											2011-08-20 22:09:37 -05:00
										 |  |  |     xendev = g_malloc0(ops->size); | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  |     object_initialize(&xendev->qdev, ops->size, TYPE_XENBACKEND); | 
					
						
							| 
									
										
										
										
											2017-02-01 07:52:02 +01:00
										 |  |  |     OBJECT(xendev)->free = g_free; | 
					
						
							|  |  |  |     qdev_set_id(DEVICE(xendev), g_strdup_printf("xen-%s-%d", type, dev)); | 
					
						
							| 
									
										
											  
											
												qdev: Convert uses of qdev_set_parent_bus() with Coccinelle
In addition to the qdev_create() patterns converted so far, we have a
qdev_set_parent_bus() pattern.  Mostly when we embed a device in a
parent device rather than allocating it on the heap.
This pattern also puts devices in the dangerous "no QOM parent, but
plugged into bus" state I explained in recent commit "qdev: New
qdev_new(), qdev_realize(), etc."
Apply same solution: convert to qdev_realize().  Coccinelle script:
    @@
    expression dev, bus, errp;
    symbol true;
    @@
    -    qdev_set_parent_bus(DEVICE(dev), bus);
         ...
    -    object_property_set_bool(OBJECT(dev), true, "realized", errp);
    +    qdev_realize(DEVICE(dev), bus, errp);
    @ depends on !(file in "qdev-monitor.c") && !(file in "hw/core/qdev.c")@
    expression dev, bus, errp;
    symbol true;
    @@
    -    qdev_set_parent_bus(dev, bus);
         ...
    -    object_property_set_bool(OBJECT(dev), true, "realized", errp);
    +    qdev_realize(dev, bus, errp);
    @@
    expression dev, bus;
    symbol true;
    @@
    -    qdev_set_parent_bus(DEVICE(dev), bus);
         ...
    -    qdev_init_nofail(DEVICE(dev));
    +    qdev_realize(DEVICE(dev), bus, &error_fatal);
Unconverted uses of qdev_set_parent_bus() remain.  They'll be
converted later in this series.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-12-armbru@redhat.com>
[Also convert new hw/virtio/vhost-user-vsock-pci.c]
											
										 
											2020-06-10 07:32:00 +02:00
										 |  |  |     qdev_realize(DEVICE(xendev), xen_sysbus, &error_fatal); | 
					
						
							| 
									
										
										
										
											2017-02-01 07:52:02 +01:00
										 |  |  |     object_unref(OBJECT(xendev)); | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     xendev->type  = type; | 
					
						
							|  |  |  |     xendev->dom   = dom; | 
					
						
							|  |  |  |     xendev->dev   = dev; | 
					
						
							|  |  |  |     xendev->ops   = ops; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-10 14:25:52 +00:00
										 |  |  |     snprintf(xendev->be, sizeof(xendev->be), "backend/%s/%d/%d", | 
					
						
							|  |  |  |              xendev->type, xendev->dom, xendev->dev); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     snprintf(xendev->name, sizeof(xendev->name), "%s-%d", | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |              xendev->type, xendev->dev); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     xendev->debug      = debug; | 
					
						
							|  |  |  |     xendev->local_port = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-15 13:23:38 +00:00
										 |  |  |     xendev->evtchndev = xenevtchn_open(NULL, 0); | 
					
						
							|  |  |  |     if (xendev->evtchndev == NULL) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(NULL, 0, "can't open evtchn device\n"); | 
					
						
							| 
									
										
										
										
											2017-02-01 07:52:02 +01:00
										 |  |  |         qdev_unplug(DEVICE(xendev), NULL); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         return NULL; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-05-09 12:04:53 -07:00
										 |  |  |     qemu_set_cloexec(xenevtchn_fd(xendev->evtchndev)); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:12 +03:00
										 |  |  |     xen_pv_insert_xendev(xendev); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     if (xendev->ops->alloc) { | 
					
						
							|  |  |  |         xendev->ops->alloc(xendev); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return xendev; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Sync internal data structures on xenstore updates. | 
					
						
							|  |  |  |  * Node specifies the changed field.  node = NULL means | 
					
						
							|  |  |  |  * update all fields (used for initialization). | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | static void xen_be_backend_changed(struct XenLegacyDevice *xendev, | 
					
						
							|  |  |  |                                    const char *node) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     if (node == NULL  ||  strcmp(node, "online") == 0) { | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         if (xenstore_read_be_int(xendev, "online", &xendev->online) == -1) { | 
					
						
							|  |  |  |             xendev->online = 0; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (node) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(xendev, 2, "backend update: %s\n", node); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         if (xendev->ops->backend_changed) { | 
					
						
							|  |  |  |             xendev->ops->backend_changed(xendev, node); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | static void xen_be_frontend_changed(struct XenLegacyDevice *xendev, | 
					
						
							|  |  |  |                                     const char *node) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int fe_state; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (node == NULL  ||  strcmp(node, "state") == 0) { | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         if (xenstore_read_fe_int(xendev, "state", &fe_state) == -1) { | 
					
						
							|  |  |  |             fe_state = XenbusStateUnknown; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (xendev->fe_state != fe_state) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |             xen_pv_printf(xendev, 1, "frontend state: %s -> %s\n", | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |                           xenbus_strstate(xendev->fe_state), | 
					
						
							|  |  |  |                           xenbus_strstate(fe_state)); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         xendev->fe_state = fe_state; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     if (node == NULL  ||  strcmp(node, "protocol") == 0) { | 
					
						
							| 
									
										
										
										
											2011-08-20 22:09:37 -05:00
										 |  |  |         g_free(xendev->protocol); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         xendev->protocol = xenstore_read_fe_str(xendev, "protocol"); | 
					
						
							|  |  |  |         if (xendev->protocol) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |             xen_pv_printf(xendev, 1, "frontend protocol: %s\n", | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:08 +03:00
										 |  |  |                           xendev->protocol); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (node) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(xendev, 2, "frontend update: %s\n", node); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         if (xendev->ops->frontend_changed) { | 
					
						
							|  |  |  |             xendev->ops->frontend_changed(xendev, node); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ------------------------------------------------------------- */ | 
					
						
							|  |  |  | /* Check for possible state transitions and perform them.        */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Initial xendev setup.  Read frontend path, register watch for it. | 
					
						
							|  |  |  |  * Should succeed once xend finished setting up the backend device. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Also sets initial state (-> Initializing) when done.  Which | 
					
						
							|  |  |  |  * only affects the xendev->be_state variable as xenbus should | 
					
						
							|  |  |  |  * already be put into that state by xend. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | static int xen_be_try_setup(struct XenLegacyDevice *xendev) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     char token[XEN_BUFSIZE]; | 
					
						
							|  |  |  |     int be_state; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (xenstore_read_be_int(xendev, "state", &be_state) == -1) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(xendev, 0, "reading backend state failed\n"); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (be_state != XenbusStateInitialising) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(xendev, 0, "initial backend state is wrong (%s)\n", | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |                       xenbus_strstate(be_state)); | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     xendev->fe = xenstore_read_be_str(xendev, "frontend"); | 
					
						
							|  |  |  |     if (xendev->fe == NULL) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(xendev, 0, "reading frontend path failed\n"); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* setup frontend watch */ | 
					
						
							|  |  |  |     snprintf(token, sizeof(token), "fe:%p", xendev); | 
					
						
							|  |  |  |     if (!xs_watch(xenstore, xendev->fe, token)) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(xendev, 0, "watching frontend path (%s) failed\n", | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |                       xendev->fe); | 
					
						
							|  |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     xen_be_set_state(xendev, XenbusStateInitialising); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     xen_be_backend_changed(xendev, NULL); | 
					
						
							|  |  |  |     xen_be_frontend_changed(xendev, NULL); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Try initialize xendev.  Prepare everything the backend can do | 
					
						
							|  |  |  |  * without synchronizing with the frontend.  Fakes hotplug-status.  No | 
					
						
							|  |  |  |  * hotplug involved here because this is about userspace drivers, thus | 
					
						
							|  |  |  |  * there are kernel backend devices which could invoke hotplug. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Goes to InitWait on success. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | static int xen_be_try_init(struct XenLegacyDevice *xendev) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int rc = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!xendev->online) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(xendev, 1, "not online\n"); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     if (xendev->ops->init) { | 
					
						
							|  |  |  |         rc = xendev->ops->init(xendev); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     if (rc != 0) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(xendev, 1, "init() failed\n"); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         return rc; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     xenstore_write_be_str(xendev, "hotplug-status", "connected"); | 
					
						
							|  |  |  |     xen_be_set_state(xendev, XenbusStateInitWait); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2011-06-17 12:15:35 +00:00
										 |  |  |  * Try to initialise xendev.  Depends on the frontend being ready | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |  * for it (shared ring and evtchn info in xenstore, state being | 
					
						
							|  |  |  |  * Initialised or Connected). | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Goes to Connected on success. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | static int xen_be_try_initialise(struct XenLegacyDevice *xendev) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int rc = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (xendev->fe_state != XenbusStateInitialised  && | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         xendev->fe_state != XenbusStateConnected) { | 
					
						
							|  |  |  |         if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |             xen_pv_printf(xendev, 2, "frontend not ready, ignoring\n"); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |             xen_pv_printf(xendev, 2, "frontend not ready (yet)\n"); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-17 16:35:51 +01:00
										 |  |  |     if (xendev->ops->flags & DEVOPS_FLAG_NEED_GNTDEV) { | 
					
						
							|  |  |  |         xendev->gnttabdev = xengnttab_open(NULL, 0); | 
					
						
							|  |  |  |         if (xendev->gnttabdev == NULL) { | 
					
						
							|  |  |  |             xen_pv_printf(NULL, 0, "can't open gnttab device\n"); | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         xendev->gnttabdev = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-17 12:15:35 +00:00
										 |  |  |     if (xendev->ops->initialise) { | 
					
						
							|  |  |  |         rc = xendev->ops->initialise(xendev); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     if (rc != 0) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(xendev, 0, "initialise() failed\n"); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         return rc; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     xen_be_set_state(xendev, XenbusStateConnected); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-06-17 12:15:35 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Try to let xendev know that it is connected.  Depends on the | 
					
						
							|  |  |  |  * frontend being Connected.  Note that this may be called more | 
					
						
							|  |  |  |  * than once since the backend state is not modified. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | static void xen_be_try_connected(struct XenLegacyDevice *xendev) | 
					
						
							| 
									
										
										
										
											2011-06-17 12:15:35 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     if (!xendev->ops->connected) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (xendev->fe_state != XenbusStateConnected) { | 
					
						
							|  |  |  |         if (xendev->ops->flags & DEVOPS_FLAG_IGNORE_STATE) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |             xen_pv_printf(xendev, 2, "frontend not ready, ignoring\n"); | 
					
						
							| 
									
										
										
										
											2011-06-17 12:15:35 +00:00
										 |  |  |         } else { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |             xen_pv_printf(xendev, 2, "frontend not ready (yet)\n"); | 
					
						
							| 
									
										
										
										
											2011-06-17 12:15:35 +00:00
										 |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     xendev->ops->connected(xendev); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Teardown connection. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Goes to Closed when done. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | static void xen_be_disconnect(struct XenLegacyDevice *xendev, | 
					
						
							|  |  |  |                               enum xenbus_state state) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     if (xendev->be_state != XenbusStateClosing && | 
					
						
							|  |  |  |         xendev->be_state != XenbusStateClosed  && | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         xendev->ops->disconnect) { | 
					
						
							|  |  |  |         xendev->ops->disconnect(xendev); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-05-17 16:35:51 +01:00
										 |  |  |     if (xendev->gnttabdev) { | 
					
						
							|  |  |  |         xengnttab_close(xendev->gnttabdev); | 
					
						
							|  |  |  |         xendev->gnttabdev = NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     if (xendev->be_state != state) { | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |         xen_be_set_state(xendev, state); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Try to reset xendev, for reconnection by another frontend instance. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | static int xen_be_try_reset(struct XenLegacyDevice *xendev) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     if (xendev->fe_state != XenbusStateInitialising) { | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |     xen_pv_printf(xendev, 1, "device reset (for re-connect)\n"); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     xen_be_set_state(xendev, XenbusStateInitialising); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * state change dispatcher function | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | void xen_be_check_state(struct XenLegacyDevice *xendev) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     int rc = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* frontend may request shutdown from almost anywhere */ | 
					
						
							|  |  |  |     if (xendev->fe_state == XenbusStateClosing || | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         xendev->fe_state == XenbusStateClosed) { | 
					
						
							|  |  |  |         xen_be_disconnect(xendev, xendev->fe_state); | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* check for possible backend state transitions */ | 
					
						
							|  |  |  |     for (;;) { | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         switch (xendev->be_state) { | 
					
						
							|  |  |  |         case XenbusStateUnknown: | 
					
						
							|  |  |  |             rc = xen_be_try_setup(xendev); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case XenbusStateInitialising: | 
					
						
							|  |  |  |             rc = xen_be_try_init(xendev); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case XenbusStateInitWait: | 
					
						
							| 
									
										
										
										
											2011-06-17 12:15:35 +00:00
										 |  |  |             rc = xen_be_try_initialise(xendev); | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         case XenbusStateConnected: | 
					
						
							|  |  |  |             /* xendev->be_state doesn't change */ | 
					
						
							|  |  |  |             xen_be_try_connected(xendev); | 
					
						
							|  |  |  |             rc = -1; | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |             break; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |         case XenbusStateClosed: | 
					
						
							|  |  |  |             rc = xen_be_try_reset(xendev); | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         default: | 
					
						
							|  |  |  |             rc = -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (rc != 0) { | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int xenstore_scan(const char *type, int dom, struct XenDevOps *ops) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  |     struct XenLegacyDevice *xendev; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     char path[XEN_BUFSIZE], token[XEN_BUFSIZE]; | 
					
						
							| 
									
										
										
										
											2013-10-10 14:25:52 +00:00
										 |  |  |     char **dev = NULL; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     unsigned int cdev, j; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* setup watch */ | 
					
						
							|  |  |  |     snprintf(token, sizeof(token), "be:%p:%d:%p", type, dom, ops); | 
					
						
							| 
									
										
										
										
											2013-10-10 14:25:52 +00:00
										 |  |  |     snprintf(path, sizeof(path), "backend/%s/%d", type, dom); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     if (!xs_watch(xenstore, path, token)) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(NULL, 0, "xen be: watching backend path (%s) failed\n", | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:08 +03:00
										 |  |  |                       path); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* look for backends */ | 
					
						
							|  |  |  |     dev = xs_directory(xenstore, 0, path, &cdev); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     if (!dev) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     for (j = 0; j < cdev; j++) { | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         xendev = xen_be_get_xendev(type, dom, atoi(dev[j]), ops); | 
					
						
							|  |  |  |         if (xendev == NULL) { | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         xen_be_check_state(xendev); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  |     free(dev); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:10 +03:00
										 |  |  | void xenstore_update_be(char *watch, char *type, int dom, | 
					
						
							|  |  |  |                         struct XenDevOps *ops) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  |     struct XenLegacyDevice *xendev; | 
					
						
							| 
									
										
										
										
											2013-10-10 14:25:52 +00:00
										 |  |  |     char path[XEN_BUFSIZE], *bepath; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     unsigned int len, dev; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-10 14:25:52 +00:00
										 |  |  |     len = snprintf(path, sizeof(path), "backend/%s/%d", type, dom); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     if (strncmp(path, watch, len) != 0) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  |     if (sscanf(watch + len, "/%u/%255s", &dev, path) != 2) { | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         strcpy(path, ""); | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  |         if (sscanf(watch + len, "/%u", &dev) != 1) { | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |             dev = -1; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (dev == -1) { | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     xendev = xen_be_get_xendev(type, dom, dev, ops); | 
					
						
							|  |  |  |     if (xendev != NULL) { | 
					
						
							| 
									
										
										
										
											2012-03-30 14:33:03 +00:00
										 |  |  |         bepath = xs_read(xenstore, 0, xendev->be, &len); | 
					
						
							|  |  |  |         if (bepath == NULL) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:19 +03:00
										 |  |  |             xen_pv_del_xendev(xendev); | 
					
						
							| 
									
										
										
										
											2012-03-30 14:33:03 +00:00
										 |  |  |         } else { | 
					
						
							|  |  |  |             free(bepath); | 
					
						
							|  |  |  |             xen_be_backend_changed(xendev, path); | 
					
						
							|  |  |  |             xen_be_check_state(xendev); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | void xenstore_update_fe(char *watch, struct XenLegacyDevice *xendev) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     char *node; | 
					
						
							|  |  |  |     unsigned int len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     len = strlen(xendev->fe); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     if (strncmp(xendev->fe, watch, len) != 0) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (watch[len] != '/') { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     node = watch + len + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     xen_be_frontend_changed(xendev, node); | 
					
						
							|  |  |  |     xen_be_check_state(xendev); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | /* -------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int xen_be_init(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-09-22 14:07:24 +02:00
										 |  |  |     xengnttab_handle *gnttabdev; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     xenstore = xs_daemon_open(); | 
					
						
							|  |  |  |     if (!xenstore) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(NULL, 0, "can't connect to xenstored\n"); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-06-04 14:45:22 +08:00
										 |  |  |     qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-10 11:07:03 +00:00
										 |  |  |     if (xen_xc == NULL || xen_fmem == NULL) { | 
					
						
							| 
									
										
										
										
											2010-08-19 12:27:56 +01:00
										 |  |  |         /* Check if xen_init() have been called */ | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         goto err; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-06-13 11:12:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-22 14:07:24 +02:00
										 |  |  |     gnttabdev = xengnttab_open(NULL, 0); | 
					
						
							|  |  |  |     if (gnttabdev != NULL) { | 
					
						
							|  |  |  |         if (xengnttab_grant_copy(gnttabdev, 0, NULL) == 0) { | 
					
						
							|  |  |  |             xen_feature_grant_copy = true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         xengnttab_close(gnttabdev); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
											  
											
												qdev: Convert uses of qdev_create() with Coccinelle
This is the transformation explained in the commit before previous.
Takes care of just one pattern that needs conversion.  More to come in
this series.
Coccinelle script:
    @ depends on !(file in "hw/arm/highbank.c")@
    expression bus, type_name, dev, expr;
    @@
    -    dev = qdev_create(bus, type_name);
    +    dev = qdev_new(type_name);
         ... when != dev = expr
    -    qdev_init_nofail(dev);
    +    qdev_realize_and_unref(dev, bus, &error_fatal);
    @@
    expression bus, type_name, dev, expr;
    identifier DOWN;
    @@
    -    dev = DOWN(qdev_create(bus, type_name));
    +    dev = DOWN(qdev_new(type_name));
         ... when != dev = expr
    -    qdev_init_nofail(DEVICE(dev));
    +    qdev_realize_and_unref(DEVICE(dev), bus, &error_fatal);
    @@
    expression bus, type_name, expr;
    identifier dev;
    @@
    -    DeviceState *dev = qdev_create(bus, type_name);
    +    DeviceState *dev = qdev_new(type_name);
         ... when != dev = expr
    -    qdev_init_nofail(dev);
    +    qdev_realize_and_unref(dev, bus, &error_fatal);
    @@
    expression bus, type_name, dev, expr, errp;
    symbol true;
    @@
    -    dev = qdev_create(bus, type_name);
    +    dev = qdev_new(type_name);
         ... when != dev = expr
    -    object_property_set_bool(OBJECT(dev), true, "realized", errp);
    +    qdev_realize_and_unref(dev, bus, errp);
    @@
    expression bus, type_name, expr, errp;
    identifier dev;
    symbol true;
    @@
    -    DeviceState *dev = qdev_create(bus, type_name);
    +    DeviceState *dev = qdev_new(type_name);
         ... when != dev = expr
    -    object_property_set_bool(OBJECT(dev), true, "realized", errp);
    +    qdev_realize_and_unref(dev, bus, errp);
The first rule exempts hw/arm/highbank.c, because it matches along two
control flow paths there, with different @type_name.  Covered by the
next commit's manual conversions.
Missing #include "qapi/error.h" added manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-10-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
											
										 
											2020-06-10 07:31:58 +02:00
										 |  |  |     xen_sysdev = qdev_new(TYPE_XENSYSDEV); | 
					
						
							| 
									
										
											  
											
												sysbus: Convert to sysbus_realize() etc. with Coccinelle
Convert from qdev_realize(), qdev_realize_and_unref() with null @bus
argument to sysbus_realize(), sysbus_realize_and_unref().
Coccinelle script:
    @@
    expression dev, errp;
    @@
    -    qdev_realize(DEVICE(dev), NULL, errp);
    +    sysbus_realize(SYS_BUS_DEVICE(dev), errp);
    @@
    expression sysbus_dev, dev, errp;
    @@
    +    sysbus_dev = SYS_BUS_DEVICE(dev);
    -    qdev_realize_and_unref(dev, NULL, errp);
    +    sysbus_realize_and_unref(sysbus_dev, errp);
    -    sysbus_dev = SYS_BUS_DEVICE(dev);
    @@
    expression sysbus_dev, dev, errp;
    expression expr;
    @@
         sysbus_dev = SYS_BUS_DEVICE(dev);
         ... when != dev = expr;
    -    qdev_realize_and_unref(dev, NULL, errp);
    +    sysbus_realize_and_unref(sysbus_dev, errp);
    @@
    expression dev, errp;
    @@
    -    qdev_realize_and_unref(DEVICE(dev), NULL, errp);
    +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
    @@
    expression dev, errp;
    @@
    -    qdev_realize_and_unref(dev, NULL, errp);
    +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), errp);
Whitespace changes minimized manually.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20200610053247.1583243-46-armbru@redhat.com>
[Conflicts in hw/misc/empty_slot.c and hw/sparc/leon3.c resolved]
											
										 
											2020-06-10 07:32:34 +02:00
										 |  |  |     sysbus_realize_and_unref(SYS_BUS_DEVICE(xen_sysdev), &error_fatal); | 
					
						
							| 
									
										
										
										
											2020-05-12 09:00:20 +02:00
										 |  |  |     xen_sysbus = qbus_create(TYPE_XENSYSBUS, xen_sysdev, "xen-sysbus"); | 
					
						
							| 
									
										
										
										
											2020-06-30 11:03:38 +02:00
										 |  |  |     qbus_set_bus_hotplug_handler(xen_sysbus); | 
					
						
							| 
									
										
										
										
											2016-06-13 11:12:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | err: | 
					
						
							|  |  |  |     qemu_set_fd_handler(xs_fileno(xenstore), NULL, NULL, NULL); | 
					
						
							|  |  |  |     xs_daemon_close(xenstore); | 
					
						
							|  |  |  |     xenstore = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  | static void xen_set_dynamic_sysbus(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Object *machine = qdev_get_machine(); | 
					
						
							|  |  |  |     ObjectClass *oc = object_get_class(machine); | 
					
						
							|  |  |  |     MachineClass *mc = MACHINE_CLASS(oc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-25 13:16:09 -02:00
										 |  |  |     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_XENSYSDEV); | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | int xen_be_register(const char *type, struct XenDevOps *ops) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-05-12 16:13:40 +02:00
										 |  |  |     char path[50]; | 
					
						
							|  |  |  |     int rc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ops->backend_register) { | 
					
						
							|  |  |  |         rc = ops->backend_register(); | 
					
						
							|  |  |  |         if (rc) { | 
					
						
							|  |  |  |             return rc; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     snprintf(path, sizeof(path), "device-model/%u/backends/%s", xen_domid, | 
					
						
							|  |  |  |              type); | 
					
						
							|  |  |  |     xenstore_mkdir(path, XS_PERM_NONE); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     return xenstore_scan(type, xen_domid, ops); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-02 08:32:32 +02:00
										 |  |  | void xen_be_register_common(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  |     xen_set_dynamic_sysbus(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-02 08:32:32 +02:00
										 |  |  |     xen_be_register("console", &xen_console_ops); | 
					
						
							|  |  |  |     xen_be_register("vkbd", &xen_kbdmouse_ops); | 
					
						
							| 
									
										
										
										
											2017-03-22 10:17:09 -07:00
										 |  |  | #ifdef CONFIG_VIRTFS
 | 
					
						
							|  |  |  |     xen_be_register("9pfs", &xen_9pfs_ops); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-08-02 08:32:32 +02:00
										 |  |  | #ifdef CONFIG_USB_LIBUSB
 | 
					
						
							|  |  |  |     xen_be_register("qusb", &xen_usb_ops); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  | int xen_be_bind_evtchn(struct XenLegacyDevice *xendev) | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |     if (xendev->local_port != -1) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-01-15 13:23:38 +00:00
										 |  |  |     xendev->local_port = xenevtchn_bind_interdomain | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         (xendev->evtchndev, xendev->dom, xendev->remote_port); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     if (xendev->local_port == -1) { | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |         xen_pv_printf(xendev, 0, "xenevtchn_bind_interdomain failed\n"); | 
					
						
							| 
									
										
										
										
											2010-09-23 12:28:45 +01:00
										 |  |  |         return -1; | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:14 +03:00
										 |  |  |     xen_pv_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port); | 
					
						
							| 
									
										
										
										
											2016-01-15 13:23:38 +00:00
										 |  |  |     qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), | 
					
						
							| 
									
										
										
										
											2016-10-25 08:50:17 +03:00
										 |  |  |                         xen_pv_evtchn_event, NULL, xendev); | 
					
						
							| 
									
										
										
										
											2009-04-22 15:19:15 +00:00
										 |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-13 11:12:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  | static Property xendev_properties[] = { | 
					
						
							|  |  |  |     DEFINE_PROP_END_OF_LIST(), | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void xendev_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     DeviceClass *dc = DEVICE_CLASS(klass); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 19:30:32 +04:00
										 |  |  |     device_class_set_props(dc, xendev_properties); | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  |     set_bit(DEVICE_CATEGORY_MISC, dc->categories); | 
					
						
							| 
									
										
										
										
											2017-05-03 17:35:46 -03:00
										 |  |  |     /* xen-backend devices can be plugged/unplugged dynamically */ | 
					
						
							| 
									
										
											  
											
												sysbus: Set user_creatable=false by default on TYPE_SYS_BUS_DEVICE
commit 33cd52b5d7b9adfd009e95f07e6c64dd88ae2a31 unset
cannot_instantiate_with_device_add_yet in TYPE_SYSBUS, making all
sysbus devices appear on "-device help" and lack the "no-user"
flag in "info qdm".
To fix this, we can set user_creatable=false by default on
TYPE_SYS_BUS_DEVICE, but this requires setting
user_creatable=true explicitly on the sysbus devices that
actually work with -device.
Fortunately today we have just a few has_dynamic_sysbus=1
machines: virt, pc-q35-*, ppce500, and spapr.
virt, ppce500, and spapr have extra checks to ensure just a few
device types can be instantiated:
* virt supports only TYPE_VFIO_CALXEDA_XGMAC, TYPE_VFIO_AMD_XGBE.
* ppce500 supports only TYPE_ETSEC_COMMON.
* spapr supports only TYPE_SPAPR_PCI_HOST_BRIDGE.
This patch sets user_creatable=true explicitly on those 4 device
classes.
Now, the more complex cases:
pc-q35-*: q35 has no sysbus device whitelist yet (which is a
separate bug). We are in the process of fixing it and building a
sysbus whitelist on q35, but in the meantime we can fix the
"-device help" and "info qdm" bugs mentioned above. Also, despite
not being strictly necessary for fixing the q35 bug, reducing the
list of user_creatable=true devices will help us be more
confident when building the q35 whitelist.
xen: We also have a hack at xen_set_dynamic_sysbus(), that sets
has_dynamic_sysbus=true at runtime when using the Xen
accelerator. This hack is only used to allow xen-backend devices
to be dynamically plugged/unplugged.
This means today we can use -device with the following 22 device
types, that are the ones compiled into the qemu-system-x86_64 and
qemu-system-i386 binaries:
* allwinner-ahci
* amd-iommu
* cfi.pflash01
* esp
* fw_cfg_io
* fw_cfg_mem
* generic-sdhci
* hpet
* intel-iommu
* ioapic
* isabus-bridge
* kvmclock
* kvm-ioapic
* kvmvapic
* SUNW,fdtwo
* sysbus-ahci
* sysbus-fdc
* sysbus-ohci
* unimplemented-device
* virtio-mmio
* xen-backend
* xen-sysdev
This patch adds user_creatable=true explicitly to those devices,
temporarily, just to keep 100% compatibility with existing
behavior of q35. Subsequent patches will remove
user_creatable=true from the devices that are really not meant to
user-creatable on any machine, and remove the FIXME comment from
the ones that are really supposed to be user-creatable. This is
being done in separate patches because we still don't have an
obvious list of devices that will be whitelisted by q35, and I
would like to get each device reviewed individually.
Cc: Alexander Graf <agraf@suse.de>
Cc: Alex Williamson <alex.williamson@redhat.com>
Cc: Alistair Francis <alistair.francis@xilinx.com>
Cc: Beniamino Galvani <b.galvani@gmail.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Cc: "Edgar E. Iglesias" <edgar.iglesias@gmail.com>
Cc: Eduardo Habkost <ehabkost@redhat.com>
Cc: Frank Blaschka <frank.blaschka@de.ibm.com>
Cc: Gabriel L. Somlo <somlo@cmu.edu>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Jason Wang <jasowang@redhat.com>
Cc: John Snow <jsnow@redhat.com>
Cc: Juergen Gross <jgross@suse.com>
Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: Markus Armbruster <armbru@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Pierre Morel <pmorel@linux.vnet.ibm.com>
Cc: Prasad J Pandit <pjp@fedoraproject.org>
Cc: qemu-arm@nongnu.org
Cc: qemu-block@nongnu.org
Cc: qemu-ppc@nongnu.org
Cc: Richard Henderson <rth@twiddle.net>
Cc: Rob Herring <robh@kernel.org>
Cc: Shannon Zhao <zhaoshenglong@huawei.com>
Cc: sstabellini@kernel.org
Cc: Thomas Huth <thuth@redhat.com>
Cc: Yi Min Zhao <zyimin@linux.vnet.ibm.com>
Acked-by: John Snow <jsnow@redhat.com>
Acked-by: Juergen Gross <jgross@suse.com>
Acked-by: Marcel Apfelbaum <marcel@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20170503203604.31462-3-ehabkost@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[ehabkost: Small changes at sysbus_device_class_init() comments]
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
											
										 
											2017-05-03 17:35:45 -03:00
										 |  |  |     dc->user_creatable = true; | 
					
						
							| 
									
										
										
										
											2020-06-24 08:19:39 -04:00
										 |  |  |     dc->bus_type = TYPE_XENSYSBUS; | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const TypeInfo xendev_type_info = { | 
					
						
							|  |  |  |     .name          = TYPE_XENBACKEND, | 
					
						
							| 
									
										
										
										
											2020-06-24 08:19:39 -04:00
										 |  |  |     .parent        = TYPE_DEVICE, | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  |     .class_init    = xendev_class_init, | 
					
						
							| 
									
										
										
										
											2019-01-08 14:48:46 +00:00
										 |  |  |     .instance_size = sizeof(struct XenLegacyDevice), | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void xen_sysbus_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     hc->unplug = qdev_simple_device_unplug_cb; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:56 +01:00
										 |  |  | static const TypeInfo xensysbus_info = { | 
					
						
							|  |  |  |     .name       = TYPE_XENSYSBUS, | 
					
						
							|  |  |  |     .parent     = TYPE_BUS, | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  |     .class_init = xen_sysbus_class_init, | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:56 +01:00
										 |  |  |     .interfaces = (InterfaceInfo[]) { | 
					
						
							|  |  |  |         { TYPE_HOTPLUG_HANDLER }, | 
					
						
							|  |  |  |         { } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-13 11:12:21 +02:00
										 |  |  | static Property xen_sysdev_properties[] = { | 
					
						
							|  |  |  |     {/* end of property list */}, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void xen_sysdev_class_init(ObjectClass *klass, void *data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     DeviceClass *dc = DEVICE_CLASS(klass); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-10 19:30:32 +04:00
										 |  |  |     device_class_set_props(dc, xen_sysdev_properties); | 
					
						
							| 
									
										
										
										
											2016-06-13 11:12:21 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const TypeInfo xensysdev_info = { | 
					
						
							|  |  |  |     .name          = TYPE_XENSYSDEV, | 
					
						
							|  |  |  |     .parent        = TYPE_SYS_BUS_DEVICE, | 
					
						
							|  |  |  |     .instance_size = sizeof(SysBusDevice), | 
					
						
							|  |  |  |     .class_init    = xen_sysdev_class_init, | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void xenbe_register_types(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:56 +01:00
										 |  |  |     type_register_static(&xensysbus_info); | 
					
						
							| 
									
										
										
										
											2016-06-13 11:12:21 +02:00
										 |  |  |     type_register_static(&xensysdev_info); | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:58 +01:00
										 |  |  |     type_register_static(&xendev_type_info); | 
					
						
							| 
									
										
										
										
											2016-06-13 11:12:21 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-22 07:10:56 +01:00
										 |  |  | type_init(xenbe_register_types) |