Index: sys/dev/hyperv/hvsock/hv_sock.c =================================================================== --- sys/dev/hyperv/hvsock/hv_sock.c +++ sys/dev/hyperv/hvsock/hv_sock.c @@ -74,6 +74,8 @@ MALLOC_DEFINE(M_HVSOCK, "hyperv_socket", "hyperv socket control structures"); +static int hvs_dom_probe(void); + /* The MTU is 16KB per host side's design */ #define HVSOCK_MTU_SIZE (1024 * 16) #define HVSOCK_SEND_BUF_SZ (PAGE_SIZE - sizeof(struct vmpipe_proto_header)) @@ -124,6 +126,7 @@ static struct domain hv_socket_domain = { .dom_family = AF_HYPERV, .dom_name = "hyperv", + .dom_probe = hvs_dom_probe, .dom_protosw = hv_socket_protosw, .dom_protoswNPROTOSW = &hv_socket_protosw[nitems(hv_socket_protosw)] }; @@ -322,6 +325,16 @@ sx_xunlock(&hvs_trans_socks_sx); } +static int +hvs_dom_probe(void) +{ + + /* Don't even give us a chance to attach on non-HyperV. */ + if (vm_guest != VM_GUEST_HV) + return (ENXIO); + return (0); +} + void hvs_trans_init(void) { @@ -329,9 +342,6 @@ if (!IS_DEFAULT_VNET(curvnet)) return; - if (vm_guest != VM_GUEST_HV) - return; - HVSOCK_DBG(HVSOCK_DBG_VERBOSE, "%s: HyperV Socket hvs_trans_init called\n", __func__); @@ -354,9 +364,6 @@ { struct hvs_pcb *pcb = so2hvspcb(so); - if (vm_guest != VM_GUEST_HV) - return (ESOCKTNOSUPPORT); - HVSOCK_DBG(HVSOCK_DBG_VERBOSE, "%s: HyperV Socket hvs_trans_attach called\n", __func__); @@ -383,9 +390,6 @@ { struct hvs_pcb *pcb; - if (vm_guest != VM_GUEST_HV) - return; - HVSOCK_DBG(HVSOCK_DBG_VERBOSE, "%s: HyperV Socket hvs_trans_detach called\n", __func__); @@ -595,9 +599,6 @@ { struct hvs_pcb *pcb; - if (vm_guest != VM_GUEST_HV) - return (ESOCKTNOSUPPORT); - HVSOCK_DBG(HVSOCK_DBG_VERBOSE, "%s: HyperV Socket hvs_trans_disconnect called\n", __func__); @@ -925,9 +926,6 @@ { struct hvs_pcb *pcb; - if (vm_guest != VM_GUEST_HV) - return; - HVSOCK_DBG(HVSOCK_DBG_VERBOSE, "%s: HyperV Socket hvs_trans_close called\n", __func__); @@ -969,9 +967,6 @@ { struct hvs_pcb *pcb = so2hvspcb(so); - if (vm_guest != VM_GUEST_HV) - return; - HVSOCK_DBG(HVSOCK_DBG_VERBOSE, "%s: HyperV Socket hvs_trans_abort called\n", __func__); Index: sys/kern/uipc_domain.c =================================================================== --- sys/kern/uipc_domain.c +++ sys/kern/uipc_domain.c @@ -170,9 +170,13 @@ void domain_init(void *arg) { - struct domain *dp = arg; + struct domain_set_args *dsa = arg; + struct domain *dp; struct protosw *pr; + if (!dsa->dsa_supported) + return; + dp = dsa->dsa_dp; if (dp->dom_init) (*dp->dom_init)(); for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) @@ -198,8 +202,12 @@ void vnet_domain_uninit(void *arg) { - struct domain *dp = arg; + struct domain_set_args *dsa = arg; + struct domain *dp; + if (!dsa->dsa_supported) + return; + dp = dsa->dsa_dp; if (dp->dom_destroy) (*dp->dom_destroy)(); } @@ -213,9 +221,14 @@ void domain_add(void *data) { + struct domain_set_args *dsa; struct domain *dp; - dp = (struct domain *)data; + dsa = data; + dp = dsa->dsa_dp; + if (dp->dom_probe != NULL && (*dp->dom_probe)() != 0) + return; + dsa->dsa_supported = 1; mtx_lock(&dom_mtx); dp->dom_next = domains; domains = dp; Index: sys/sys/domain.h =================================================================== --- sys/sys/domain.h +++ sys/sys/domain.h @@ -49,6 +49,7 @@ struct domain { int dom_family; /* AF_xxx */ char *dom_name; + int (*dom_probe)(void); /* check for support (optional) */ void (*dom_init) /* initialize domain data structures */ (void); void (*dom_destroy) /* cleanup structures / state */ @@ -79,20 +80,36 @@ void vnet_domain_uninit(void *); #endif +struct domain_set_args { + struct domain *dsa_dp; + int dsa_supported; +}; + #define DOMAIN_SET(name) \ + static struct domain_set_args name ## domain_set_args = { \ + .dsa_dp = & name ## domain, \ + }; \ SYSINIT(domain_add_ ## name, SI_SUB_PROTO_DOMAIN, \ - SI_ORDER_FIRST, domain_add, & name ## domain); \ + SI_ORDER_FIRST, domain_add, &name ## domain_set_args); \ SYSINIT(domain_init_ ## name, SI_SUB_PROTO_DOMAIN, \ - SI_ORDER_SECOND, domain_init, & name ## domain); + SI_ORDER_SECOND, domain_init, &name ## domain_set_args); #ifdef VIMAGE +/* + * There's no such thing as per-vnet domains, so domain_set_args don't really + * need to be virtualized at the moment. Further consideration would be needed + * for such a concept to work at all. + */ #define VNET_DOMAIN_SET(name) \ + static struct domain_set_args name ## domain_set_args = { \ + .dsa_dp = & name ## domain, \ + }; \ SYSINIT(domain_add_ ## name, SI_SUB_PROTO_DOMAIN, \ - SI_ORDER_FIRST, domain_add, & name ## domain); \ + SI_ORDER_FIRST, domain_add, &name ## domain_set_args); \ VNET_SYSINIT(vnet_domain_init_ ## name, SI_SUB_PROTO_DOMAIN, \ - SI_ORDER_SECOND, vnet_domain_init, & name ## domain); \ + SI_ORDER_SECOND, vnet_domain_init, &name ## domain_set_args); \ VNET_SYSUNINIT(vnet_domain_uninit_ ## name, \ SI_SUB_PROTO_DOMAIN, SI_ORDER_SECOND, vnet_domain_uninit, \ - & name ## domain) + &name ## domain_set_args); #else /* !VIMAGE */ #define VNET_DOMAIN_SET(name) DOMAIN_SET(name) #endif /* VIMAGE */