131e37bb4Svn83148 /* 231e37bb4Svn83148 * CDDL HEADER START 331e37bb4Svn83148 * 431e37bb4Svn83148 * The contents of this file are subject to the terms of the 531e37bb4Svn83148 * Common Development and Distribution License (the "License"). 631e37bb4Svn83148 * You may not use this file except in compliance with the License. 731e37bb4Svn83148 * 831e37bb4Svn83148 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 931e37bb4Svn83148 * or http://www.opensolaris.org/os/licensing. 1031e37bb4Svn83148 * See the License for the specific language governing permissions 1131e37bb4Svn83148 * and limitations under the License. 1231e37bb4Svn83148 * 1331e37bb4Svn83148 * When distributing Covered Code, include this CDDL HEADER in each 1431e37bb4Svn83148 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1531e37bb4Svn83148 * If applicable, add the following below this CDDL HEADER, with the 1631e37bb4Svn83148 * fields enclosed by brackets "[]" replaced with your own identifying 1731e37bb4Svn83148 * information: Portions Copyright [yyyy] [name of copyright owner] 1831e37bb4Svn83148 * 1931e37bb4Svn83148 * CDDL HEADER END 2031e37bb4Svn83148 */ 2131e37bb4Svn83148 /* 225f149bcaScy152378 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2331e37bb4Svn83148 * Use is subject to license terms. 2431e37bb4Svn83148 */ 2531e37bb4Svn83148 2631e37bb4Svn83148 #include <stdio.h> 2731e37bb4Svn83148 #include <unistd.h> 2831e37bb4Svn83148 #include <stdlib.h> 2931e37bb4Svn83148 #include <string.h> 3025351652SVuong Nguyen #include <strings.h> 3131e37bb4Svn83148 #include <fcntl.h> 3231e37bb4Svn83148 #include <pthread.h> 3331e37bb4Svn83148 #include <errno.h> 3431e37bb4Svn83148 #include <libnvpair.h> 35c94f2192Srb144127 #include <dlfcn.h> 36c94f2192Srb144127 #include <link.h> 37c3b50bc5Srb144127 #include <assert.h> 3831e37bb4Svn83148 3925351652SVuong Nguyen #include <fm/libtopo.h> 4031e37bb4Svn83148 #include <sys/processor.h> 4131e37bb4Svn83148 #include <sys/stat.h> 4231e37bb4Svn83148 #include <sys/mdesc.h> 4331e37bb4Svn83148 #include <sys/param.h> 4431e37bb4Svn83148 #include <sys/systeminfo.h> 4531e37bb4Svn83148 #include <sys/mem.h> 4631e37bb4Svn83148 #include <sys/bl.h> 4731e37bb4Svn83148 #include <sys/fm/protocol.h> 4831e37bb4Svn83148 #include <fm/fmd_fmri.h> 49e4b86885SCheng Sean Ye #include <fm/fmd_agent.h> 50ef884685Srb144127 #include <sys/pri.h> 5131e37bb4Svn83148 5231e37bb4Svn83148 #include "ldom.h" 5325351652SVuong Nguyen #include "ldom_alloc.h" 5431e37bb4Svn83148 #include "ldmsvcs_utils.h" 5525351652SVuong Nguyen #include "ldom_xmpp_client.h" 5631e37bb4Svn83148 57c37dbf9cSvn83148 #define MD_STR_PLATFORM "platform" 58c3b50bc5Srb144127 #define MD_STR_DOM_CAPABLE "domaining-enabled" 5925351652SVuong Nguyen #define MD_STR_IODEVICE "iodevice" 6025351652SVuong Nguyen #define MD_STR_NAME "name" 6125351652SVuong Nguyen #define MD_STR_DEVICE_TYPE "device-type" 6225351652SVuong Nguyen #define MD_STR_CFGHDL "cfg-handle" 6325351652SVuong Nguyen #define MD_STR_PCIEX "pciex" 6425351652SVuong Nguyen #define MD_STR_PCI "pci" 6525351652SVuong Nguyen #define MD_STR_NIU "niu" 66c3b50bc5Srb144127 67c3b50bc5Srb144127 static int ldom_ldmd_is_up = 0; /* assume stays up if ever seen up */ 6831e37bb4Svn83148 69c94f2192Srb144127 static void *ldom_dl_hp = (void *)NULL; 70c94f2192Srb144127 static const char *ldom_dl_path = "libpri.so.1"; 71c94f2192Srb144127 static int ldom_dl_mode = (RTLD_NOW | RTLD_LOCAL); 72c94f2192Srb144127 73c3b50bc5Srb144127 static pthread_mutex_t ldom_pri_lock = PTHREAD_MUTEX_INITIALIZER; 74c3b50bc5Srb144127 static int ldom_pri_ref_cnt = 0; /* num of outstanding ldom_pri_init()s */ 75c3b50bc5Srb144127 static int ldom_pri_init_done = 0; /* bool for real pri_init() done */ 76c3b50bc5Srb144127 static int (*ldom_pri_fp_init)(void) = (int (*)(void))NULL; 77c3b50bc5Srb144127 static void (*ldom_pri_fp_fini)(void) = (void (*)(void))NULL; 78c3b50bc5Srb144127 static ssize_t (*ldom_pri_fp_get)(uint8_t wait, uint64_t *token, uint64_t **buf, 79c94f2192Srb144127 void *(*allocp)(size_t), void (*freep)(void *, size_t)) = 80c94f2192Srb144127 (ssize_t (*)(uint8_t wait, uint64_t *token, uint64_t **buf, 81c94f2192Srb144127 void *(*allocp)(size_t), void (*freep)(void *, size_t)))NULL; 82c94f2192Srb144127 83c94f2192Srb144127 static void 84c94f2192Srb144127 ldom_pri_config(void) 85c94f2192Srb144127 { 86c94f2192Srb144127 char isa[MAXNAMELEN]; /* used to see if machine is sun4v */ 87c94f2192Srb144127 88c94f2192Srb144127 if (sysinfo(SI_MACHINE, isa, MAXNAMELEN) < 0) 89c94f2192Srb144127 return; 90c94f2192Srb144127 if (strcmp(isa, "sun4v") != 0) 91c94f2192Srb144127 return; 92c94f2192Srb144127 if ((ldom_dl_hp = dlopen(ldom_dl_path, ldom_dl_mode)) == NULL) 93c94f2192Srb144127 return; 94c94f2192Srb144127 95c3b50bc5Srb144127 ldom_pri_fp_init = (int (*)(void))dlsym(ldom_dl_hp, "pri_init"); 96c3b50bc5Srb144127 ldom_pri_fp_fini = (void (*)(void))dlsym(ldom_dl_hp, "pri_fini"); 97c3b50bc5Srb144127 ldom_pri_fp_get = (ssize_t (*)(uint8_t wait, uint64_t *token, 98c94f2192Srb144127 uint64_t **buf, void *(*allocp)(size_t), 99c94f2192Srb144127 void (*freep)(void *, size_t)))dlsym(ldom_dl_hp, "pri_get"); 100c94f2192Srb144127 } 101c94f2192Srb144127 102c94f2192Srb144127 static void 103c94f2192Srb144127 ldom_pri_unconfig(void) 104c94f2192Srb144127 { 105c94f2192Srb144127 if (ldom_dl_hp == NULL) 106c94f2192Srb144127 return; 107c94f2192Srb144127 108c3b50bc5Srb144127 ldom_pri_fp_init = (int (*)(void))NULL; 109c3b50bc5Srb144127 ldom_pri_fp_fini = (void (*)(void))NULL; 110c3b50bc5Srb144127 ldom_pri_fp_get = (ssize_t (*)(uint8_t wait, uint64_t *token, 111c94f2192Srb144127 uint64_t **buf, void *(*allocp)(size_t), 112c94f2192Srb144127 void (*freep)(void *, size_t)))NULL; 113c94f2192Srb144127 (void) dlclose(ldom_dl_hp); 114c94f2192Srb144127 ldom_dl_hp = (void *)NULL; 115c94f2192Srb144127 } 116c94f2192Srb144127 117c3b50bc5Srb144127 /* 118c3b50bc5Srb144127 * ldom_pri_lock is assumed already held by anyone accessing ldom_pri_ref_cnt 119c3b50bc5Srb144127 */ 120c3b50bc5Srb144127 121c3b50bc5Srb144127 static int 122c3b50bc5Srb144127 ldom_pri_init(void) 123c3b50bc5Srb144127 { 124c3b50bc5Srb144127 if (ldom_pri_ref_cnt == 0) { 125c3b50bc5Srb144127 ldom_pri_config(); 126c3b50bc5Srb144127 /* 127c3b50bc5Srb144127 * ldom_pri_init() is called before we know whether we 128c3b50bc5Srb144127 * have LDOMS FW or not; defer calling pri_init() via 129c3b50bc5Srb144127 * ldom_pri_fp_init until the first time we try to 130c3b50bc5Srb144127 * actually get a PRI 131c3b50bc5Srb144127 */ 132c3b50bc5Srb144127 } 133c3b50bc5Srb144127 ldom_pri_ref_cnt++; 134c3b50bc5Srb144127 135c3b50bc5Srb144127 assert(ldom_pri_ref_cnt > 0); 136c3b50bc5Srb144127 137c3b50bc5Srb144127 return (0); 138c3b50bc5Srb144127 } 139c3b50bc5Srb144127 140c3b50bc5Srb144127 static void 141c3b50bc5Srb144127 ldom_pri_fini(void) 142c3b50bc5Srb144127 { 143c3b50bc5Srb144127 assert(ldom_pri_ref_cnt > 0); 144c3b50bc5Srb144127 145c3b50bc5Srb144127 ldom_pri_ref_cnt--; 146c3b50bc5Srb144127 if (ldom_pri_ref_cnt == 0) { 147c3b50bc5Srb144127 if (ldom_pri_init_done && (ldom_pri_fp_fini != NULL)) { 148c3b50bc5Srb144127 (*ldom_pri_fp_fini)(); 149c3b50bc5Srb144127 ldom_pri_init_done = 0; 150c3b50bc5Srb144127 } 151c3b50bc5Srb144127 ldom_pri_unconfig(); 152c3b50bc5Srb144127 } 153c3b50bc5Srb144127 } 154c3b50bc5Srb144127 155c3b50bc5Srb144127 static ssize_t 156c3b50bc5Srb144127 ldom_pri_get(uint8_t wait, uint64_t *token, uint64_t **buf, 157c3b50bc5Srb144127 void *(*allocp)(size_t), void (*freep)(void *, size_t)) 158c3b50bc5Srb144127 { 159c3b50bc5Srb144127 assert(ldom_pri_ref_cnt > 0); 160c3b50bc5Srb144127 161c3b50bc5Srb144127 if ((!ldom_pri_init_done) && (ldom_pri_fp_init != NULL)) { 162c3b50bc5Srb144127 if ((*ldom_pri_fp_init)() < 0) 163c3b50bc5Srb144127 return (-1); 164c3b50bc5Srb144127 ldom_pri_init_done = 1; 165c3b50bc5Srb144127 } 166c3b50bc5Srb144127 167c3b50bc5Srb144127 if (ldom_pri_fp_get != NULL) 168c3b50bc5Srb144127 return ((*ldom_pri_fp_get)(wait, token, buf, allocp, freep)); 169c3b50bc5Srb144127 else 170c3b50bc5Srb144127 return (-1); 171c3b50bc5Srb144127 } 172c3b50bc5Srb144127 17331e37bb4Svn83148 static ssize_t 17431e37bb4Svn83148 get_local_core_md(ldom_hdl_t *lhp, uint64_t **buf) 17531e37bb4Svn83148 { 17631e37bb4Svn83148 int fh; 17731e37bb4Svn83148 size_t size; 17831e37bb4Svn83148 uint64_t *bufp; 17931e37bb4Svn83148 18031e37bb4Svn83148 if ((fh = open("/devices/pseudo/mdesc@0:mdesc", O_RDONLY, 0)) < 0) 18131e37bb4Svn83148 return (-1); 18231e37bb4Svn83148 18331e37bb4Svn83148 if (ioctl(fh, MDESCIOCGSZ, &size) < 0) { 18431e37bb4Svn83148 (void) close(fh); 18531e37bb4Svn83148 return (-1); 18631e37bb4Svn83148 } 18731e37bb4Svn83148 18831e37bb4Svn83148 bufp = (uint64_t *)lhp->allocp(size); 18931e37bb4Svn83148 19031e37bb4Svn83148 if (read(fh, bufp, size) < 0) { 19131e37bb4Svn83148 lhp->freep(bufp, size); 19231e37bb4Svn83148 (void) close(fh); 19331e37bb4Svn83148 return (-1); 19431e37bb4Svn83148 } 19531e37bb4Svn83148 (void) close(fh); 19631e37bb4Svn83148 19731e37bb4Svn83148 *buf = bufp; 19831e37bb4Svn83148 19931e37bb4Svn83148 return ((ssize_t)size); 20031e37bb4Svn83148 } 20131e37bb4Svn83148 20231e37bb4Svn83148 20331e37bb4Svn83148 static int 204c37dbf9cSvn83148 get_local_md_prop_value(ldom_hdl_t *lhp, char *node, char *prop, uint64_t *val) 205c37dbf9cSvn83148 { 206c37dbf9cSvn83148 int rc = 1; 207c37dbf9cSvn83148 uint64_t *bufp; 208c37dbf9cSvn83148 ssize_t bufsiz; 209c37dbf9cSvn83148 210c37dbf9cSvn83148 if ((bufsiz = get_local_core_md(lhp, &bufp)) > 0) { 211c37dbf9cSvn83148 md_t *mdp; 212c37dbf9cSvn83148 213c37dbf9cSvn83148 if (mdp = md_init_intern(bufp, lhp->allocp, lhp->freep)) { 214c37dbf9cSvn83148 int num_nodes; 215c37dbf9cSvn83148 mde_cookie_t *listp; 216c37dbf9cSvn83148 217c37dbf9cSvn83148 num_nodes = md_node_count(mdp); 218c37dbf9cSvn83148 listp = lhp->allocp(sizeof (mde_cookie_t) * num_nodes); 219c37dbf9cSvn83148 220c37dbf9cSvn83148 if (md_scan_dag(mdp, MDE_INVAL_ELEM_COOKIE, 221c37dbf9cSvn83148 md_find_name(mdp, node), 222c3b50bc5Srb144127 md_find_name(mdp, "fwd"), listp) > 0 && 223c37dbf9cSvn83148 md_get_prop_val(mdp, listp[0], prop, val) >= 0) { 224c37dbf9cSvn83148 /* found the property */ 225c37dbf9cSvn83148 rc = 0; 226c37dbf9cSvn83148 } 227c37dbf9cSvn83148 228c37dbf9cSvn83148 lhp->freep(listp, sizeof (mde_cookie_t) * num_nodes); 229c37dbf9cSvn83148 (void) md_fini(mdp); 230c37dbf9cSvn83148 } 231c37dbf9cSvn83148 lhp->freep(bufp, bufsiz); 232c37dbf9cSvn83148 } 233c37dbf9cSvn83148 return (rc); 234c37dbf9cSvn83148 } 235c37dbf9cSvn83148 23631e37bb4Svn83148 /* 23731e37bb4Svn83148 * search the machine description for a "pid" entry (physical cpuid) and 238c3b50bc5Srb144127 * return the corresponding "id" entry (virtual cpuid). 239c3b50bc5Srb144127 * return -1 if not found. 240c3b50bc5Srb144127 * if the pid property does not exist in a cpu node, assume pid = id. 24131e37bb4Svn83148 */ 24231e37bb4Svn83148 static processorid_t 24331e37bb4Svn83148 cpu_phys2virt(ldom_hdl_t *lhp, uint32_t cpuid) 24431e37bb4Svn83148 { 24531e37bb4Svn83148 char isa[MAXNAMELEN]; 24631e37bb4Svn83148 md_t *mdp; 24731e37bb4Svn83148 mde_cookie_t *listp; 24831e37bb4Svn83148 ssize_t bufsize; 24931e37bb4Svn83148 processorid_t vid; 25031e37bb4Svn83148 uint64_t *bufp; 251c3b50bc5Srb144127 uint64_t pval, pid, id; 25231e37bb4Svn83148 int num_nodes, ncpus, i; 25331e37bb4Svn83148 254c3b50bc5Srb144127 (void) sysinfo(SI_MACHINE, isa, MAXNAMELEN); 25531e37bb4Svn83148 25631e37bb4Svn83148 if (strcmp(isa, "sun4v") != 0) 25731e37bb4Svn83148 return ((processorid_t)cpuid); 25831e37bb4Svn83148 25931e37bb4Svn83148 /* 26031e37bb4Svn83148 * convert the physical cpuid to a virtual cpuid 26131e37bb4Svn83148 */ 262c3b50bc5Srb144127 if ((bufsize = get_local_core_md(lhp, &bufp)) < 1) 26331e37bb4Svn83148 return (-1); 26431e37bb4Svn83148 26531e37bb4Svn83148 if ((mdp = md_init_intern(bufp, lhp->allocp, lhp->freep)) == NULL || 26631e37bb4Svn83148 (num_nodes = md_node_count(mdp)) < 1) { 26731e37bb4Svn83148 lhp->freep(bufp, bufsize); 26831e37bb4Svn83148 return (-1); 26931e37bb4Svn83148 } 27031e37bb4Svn83148 27131e37bb4Svn83148 listp = (mde_cookie_t *)lhp->allocp(sizeof (mde_cookie_t) * num_nodes); 27231e37bb4Svn83148 ncpus = md_scan_dag(mdp, MDE_INVAL_ELEM_COOKIE, 273c3b50bc5Srb144127 md_find_name(mdp, "cpu"), md_find_name(mdp, "fwd"), listp); 27431e37bb4Svn83148 27531e37bb4Svn83148 vid = -1; 27631e37bb4Svn83148 for (i = 0; i < ncpus; i++) { 277c3b50bc5Srb144127 if (md_get_prop_val(mdp, listp[i], "id", &pval) < 0) 278c3b50bc5Srb144127 pval = (uint64_t)-1; 279c3b50bc5Srb144127 id = pval; 28031e37bb4Svn83148 281c3b50bc5Srb144127 /* if pid does not exist, assume pid=id */ 282c3b50bc5Srb144127 if (md_get_prop_val(mdp, listp[i], "pid", &pval) < 0) 283c3b50bc5Srb144127 pval = id; 284c3b50bc5Srb144127 pid = pval; 285c3b50bc5Srb144127 286c3b50bc5Srb144127 if (pid == (uint64_t)cpuid) { 287c3b50bc5Srb144127 /* Found the entry */ 288c3b50bc5Srb144127 vid = (processorid_t)id; 28931e37bb4Svn83148 break; 29031e37bb4Svn83148 } 29131e37bb4Svn83148 } 29231e37bb4Svn83148 29331e37bb4Svn83148 lhp->freep(listp, sizeof (mde_cookie_t) * num_nodes); 29431e37bb4Svn83148 (void) md_fini(mdp); 29531e37bb4Svn83148 lhp->freep(bufp, bufsize); 29631e37bb4Svn83148 29731e37bb4Svn83148 return (vid); 29831e37bb4Svn83148 } 29931e37bb4Svn83148 30025351652SVuong Nguyen static int 30125351652SVuong Nguyen get_type(ldom_hdl_t *lhp, uint32_t *type) 30225351652SVuong Nguyen { 30325351652SVuong Nguyen int num_nodes, cnt, i, rc; 30425351652SVuong Nguyen char *p; 30525351652SVuong Nguyen mde_cookie_t *listp; 30625351652SVuong Nguyen md_t *mdp; 30725351652SVuong Nguyen uint64_t domain_capable; 30825351652SVuong Nguyen uint64_t *bufp; 30925351652SVuong Nguyen ssize_t bufsize; 31025351652SVuong Nguyen 31125351652SVuong Nguyen *type = 0; 31225351652SVuong Nguyen 31325351652SVuong Nguyen /* legacy system */ 31425351652SVuong Nguyen if (get_local_md_prop_value(lhp, MD_STR_PLATFORM, MD_STR_DOM_CAPABLE, 31525351652SVuong Nguyen &domain_capable) != 0) { 31625351652SVuong Nguyen *type = LDOM_TYPE_LEGACY; 31725351652SVuong Nguyen return (0); 31825351652SVuong Nguyen } 31925351652SVuong Nguyen 32025351652SVuong Nguyen /* 32125351652SVuong Nguyen * LDOMS capable FW is installed; it should be ok to 32225351652SVuong Nguyen * try to communicate with ldmd 32325351652SVuong Nguyen */ 32425351652SVuong Nguyen if ((rc = ldmsvcs_check_channel()) == 0) { 32525351652SVuong Nguyen /* 32625351652SVuong Nguyen * control ldom 32725351652SVuong Nguyen * ldmfma channel between FMA and ldmd only exists 32825351652SVuong Nguyen * on the control domain. 32925351652SVuong Nguyen */ 33025351652SVuong Nguyen *type |= LDOM_TYPE_CONTROL; 33125351652SVuong Nguyen } else if (rc == -1) { 33225351652SVuong Nguyen return (rc); 33325351652SVuong Nguyen } 33425351652SVuong Nguyen 33525351652SVuong Nguyen /* 33625351652SVuong Nguyen * root domain and io domain 33725351652SVuong Nguyen */ 33825351652SVuong Nguyen if ((bufsize = get_local_core_md(lhp, &bufp)) < 1) 33925351652SVuong Nguyen return (-1); 34025351652SVuong Nguyen if ((mdp = md_init_intern(bufp, lhp->allocp, lhp->freep)) == NULL) { 34125351652SVuong Nguyen lhp->freep(bufp, bufsize); 34225351652SVuong Nguyen return (-1); 34325351652SVuong Nguyen } 34425351652SVuong Nguyen if ((num_nodes = md_node_count(mdp)) < 1) { 34525351652SVuong Nguyen lhp->freep(bufp, bufsize); 34625351652SVuong Nguyen (void) md_fini(mdp); 34725351652SVuong Nguyen return (-1); 34825351652SVuong Nguyen } 34925351652SVuong Nguyen 35025351652SVuong Nguyen /* Search for the root complex and niu nodes */ 35125351652SVuong Nguyen listp = lhp->allocp(sizeof (mde_cookie_t) * num_nodes); 35225351652SVuong Nguyen cnt = md_scan_dag(mdp, MDE_INVAL_ELEM_COOKIE, 35325351652SVuong Nguyen md_find_name(mdp, MD_STR_IODEVICE), md_find_name(mdp, "fwd"), 35425351652SVuong Nguyen listp); 35525351652SVuong Nguyen for (i = 0, p = NULL; i < cnt; i++) { 35625351652SVuong Nguyen if ((md_get_prop_str(mdp, listp[i], MD_STR_DEVICE_TYPE, &p) 35725351652SVuong Nguyen == 0) && 35825351652SVuong Nguyen (p != NULL) && (strcmp(p, MD_STR_PCIEX) == 0)) { 35925351652SVuong Nguyen *type |= LDOM_TYPE_ROOT; 36025351652SVuong Nguyen break; 36125351652SVuong Nguyen } 36225351652SVuong Nguyen } 36325351652SVuong Nguyen for (i = 0, p = NULL; i < cnt; i++) { 36425351652SVuong Nguyen if ((md_get_prop_str(mdp, listp[i], MD_STR_NAME, &p) == 0) && 36525351652SVuong Nguyen (p != NULL) && (strcmp(p, MD_STR_NIU) == 0)) { 36625351652SVuong Nguyen *type |= LDOM_TYPE_IO; 36725351652SVuong Nguyen break; 36825351652SVuong Nguyen } 36925351652SVuong Nguyen } 37025351652SVuong Nguyen lhp->freep(listp, sizeof (mde_cookie_t) * num_nodes); 37125351652SVuong Nguyen (void) md_fini(mdp); 37225351652SVuong Nguyen lhp->freep(bufp, bufsize); 37325351652SVuong Nguyen 37425351652SVuong Nguyen return (0); 37525351652SVuong Nguyen } 37625351652SVuong Nguyen 37725351652SVuong Nguyen int 37825351652SVuong Nguyen ldom_get_type(ldom_hdl_t *lhp, uint32_t *type) 37925351652SVuong Nguyen { 38025351652SVuong Nguyen static pthread_mutex_t mt = PTHREAD_MUTEX_INITIALIZER; 38125351652SVuong Nguyen static pthread_cond_t cv = PTHREAD_COND_INITIALIZER; 38225351652SVuong Nguyen static uint32_t ltype = 0; 38325351652SVuong Nguyen static int busy_init = 0; 38425351652SVuong Nguyen 38525351652SVuong Nguyen int rc = 0; 38625351652SVuong Nguyen 38725351652SVuong Nguyen (void) pthread_mutex_lock(&mt); 38825351652SVuong Nguyen 38925351652SVuong Nguyen while (busy_init == 1) 39025351652SVuong Nguyen (void) pthread_cond_wait(&cv, &mt); 39125351652SVuong Nguyen 39225351652SVuong Nguyen if (VALID_LDOM_TYPE(ltype) != 0) { 39325351652SVuong Nguyen *type = ltype; 39425351652SVuong Nguyen (void) pthread_mutex_unlock(&mt); 39525351652SVuong Nguyen return (0); 39625351652SVuong Nguyen } 39725351652SVuong Nguyen 39825351652SVuong Nguyen /* 39925351652SVuong Nguyen * get to this point if the ldom_type has not yet been determined 40025351652SVuong Nguyen */ 40125351652SVuong Nguyen busy_init = 1; 40225351652SVuong Nguyen (void) pthread_mutex_unlock(&mt); 40325351652SVuong Nguyen 40425351652SVuong Nguyen rc = get_type(lhp, <ype); 40525351652SVuong Nguyen if (rc == 0) { 40625351652SVuong Nguyen *type = ltype; 40725351652SVuong Nguyen } 40825351652SVuong Nguyen 40925351652SVuong Nguyen (void) pthread_mutex_lock(&mt); 41025351652SVuong Nguyen busy_init = 0; 41125351652SVuong Nguyen (void) pthread_mutex_unlock(&mt); 41225351652SVuong Nguyen 41325351652SVuong Nguyen (void) pthread_cond_broadcast(&cv); 41425351652SVuong Nguyen 41525351652SVuong Nguyen return (rc); 41625351652SVuong Nguyen } 41725351652SVuong Nguyen 41831e37bb4Svn83148 int 41931e37bb4Svn83148 ldom_fmri_status(ldom_hdl_t *lhp, nvlist_t *nvl) 42031e37bb4Svn83148 { 42131e37bb4Svn83148 char *name; 422c3b50bc5Srb144127 int ret = ENOTSUP; 42331e37bb4Svn83148 42431e37bb4Svn83148 if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &name) != 0) 42531e37bb4Svn83148 return (EINVAL); 42631e37bb4Svn83148 42731e37bb4Svn83148 /* 42825351652SVuong Nguyen * ldom_ldmd_is_up can only be true if a pri can be obtained from ldmd. 42931e37bb4Svn83148 */ 430c3b50bc5Srb144127 if (!ldom_ldmd_is_up) { 431c3b50bc5Srb144127 /* Zeus is unavail; use local routines for status/retire */ 432c3b50bc5Srb144127 43331e37bb4Svn83148 if (strcmp(name, FM_FMRI_SCHEME_CPU) == 0) { 43431e37bb4Svn83148 processorid_t vid; 43531e37bb4Svn83148 uint32_t cpuid; 43631e37bb4Svn83148 437c3b50bc5Srb144127 if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) 438c3b50bc5Srb144127 == 0 && (vid = cpu_phys2virt(lhp, cpuid)) != -1) 43931e37bb4Svn83148 return (p_online(vid, P_STATUS)); 44031e37bb4Svn83148 } else if (strcmp(name, FM_FMRI_SCHEME_MEM) == 0) { 441e4b86885SCheng Sean Ye fmd_agent_hdl_t *hdl; 442e4b86885SCheng Sean Ye int err; 443e4b86885SCheng Sean Ye if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) == NULL) { 444e4b86885SCheng Sean Ye err = errno; 445e4b86885SCheng Sean Ye } else { 446e4b86885SCheng Sean Ye err = fmd_agent_page_isretired(hdl, nvl); 447e4b86885SCheng Sean Ye if (err == FMD_AGENT_RETIRE_DONE) 448e4b86885SCheng Sean Ye err = 0; 449e4b86885SCheng Sean Ye else 450e4b86885SCheng Sean Ye err = fmd_agent_errno(hdl); 451e4b86885SCheng Sean Ye fmd_agent_close(hdl); 452e4b86885SCheng Sean Ye } 453e4b86885SCheng Sean Ye return (err); 45431e37bb4Svn83148 } 45531e37bb4Svn83148 45631e37bb4Svn83148 return (EINVAL); 457c3b50bc5Srb144127 } else { 458c3b50bc5Srb144127 /* Zeus is avail; use Zeus for status/retire */ 459c3b50bc5Srb144127 46031e37bb4Svn83148 if (strcmp(name, FM_FMRI_SCHEME_CPU) == 0) { 46131e37bb4Svn83148 uint32_t cpuid; 46231e37bb4Svn83148 46331e37bb4Svn83148 if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, 46431e37bb4Svn83148 &cpuid) == 0) 46531e37bb4Svn83148 ret = ldmsvcs_cpu_req_status(lhp, cpuid); 46631e37bb4Svn83148 } else if (strcmp(name, FM_FMRI_SCHEME_MEM) == 0) { 46731e37bb4Svn83148 uint64_t pa; 46831e37bb4Svn83148 46931e37bb4Svn83148 if (nvlist_lookup_uint64(nvl, FM_FMRI_MEM_PHYSADDR, 47031e37bb4Svn83148 &pa) == 0) 47131e37bb4Svn83148 ret = ldmsvcs_mem_req_status(lhp, pa); 47231e37bb4Svn83148 else 47331e37bb4Svn83148 ret = EINVAL; 47431e37bb4Svn83148 } 47531e37bb4Svn83148 return (ret); 47631e37bb4Svn83148 } 47731e37bb4Svn83148 } 47831e37bb4Svn83148 47931e37bb4Svn83148 48031e37bb4Svn83148 int 48131e37bb4Svn83148 ldom_fmri_retire(ldom_hdl_t *lhp, nvlist_t *nvl) 48231e37bb4Svn83148 { 48331e37bb4Svn83148 char *name; 484c3b50bc5Srb144127 int ret = ENOTSUP; 48531e37bb4Svn83148 48631e37bb4Svn83148 if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &name) != 0) 48731e37bb4Svn83148 return (EINVAL); 48831e37bb4Svn83148 48931e37bb4Svn83148 /* 49025351652SVuong Nguyen * ldom_ldmd_is_up can only be true if a pri can be obtained from ldmd. 49131e37bb4Svn83148 */ 492c3b50bc5Srb144127 if (!ldom_ldmd_is_up) { 493c3b50bc5Srb144127 /* Zeus is unavail; use local routines for status/retire */ 494c3b50bc5Srb144127 49531e37bb4Svn83148 if (strcmp(name, FM_FMRI_SCHEME_CPU) == 0) { 49631e37bb4Svn83148 processorid_t vid; 49731e37bb4Svn83148 uint32_t cpuid; 49831e37bb4Svn83148 499c3b50bc5Srb144127 if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) 500c3b50bc5Srb144127 == 0 && (vid = cpu_phys2virt(lhp, cpuid)) != -1) 50131e37bb4Svn83148 return (p_online(vid, P_FAULTED)); 50231e37bb4Svn83148 } else if (strcmp(name, FM_FMRI_SCHEME_MEM) == 0) { 503e4b86885SCheng Sean Ye fmd_agent_hdl_t *hdl; 504e4b86885SCheng Sean Ye int err; 505e4b86885SCheng Sean Ye if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) == NULL) { 506e4b86885SCheng Sean Ye err = errno; 507e4b86885SCheng Sean Ye } else { 508e4b86885SCheng Sean Ye err = fmd_agent_page_retire(hdl, nvl); 509e4b86885SCheng Sean Ye if (err == FMD_AGENT_RETIRE_DONE) 510e4b86885SCheng Sean Ye err = 0; 511e4b86885SCheng Sean Ye else 512e4b86885SCheng Sean Ye err = fmd_agent_errno(hdl); 513e4b86885SCheng Sean Ye fmd_agent_close(hdl); 514e4b86885SCheng Sean Ye } 515e4b86885SCheng Sean Ye return (err); 51631e37bb4Svn83148 } 51731e37bb4Svn83148 51831e37bb4Svn83148 return (EINVAL); 519c3b50bc5Srb144127 } else { 520c3b50bc5Srb144127 /* Zeus is avail; use Zeus for status/retire */ 521c3b50bc5Srb144127 52231e37bb4Svn83148 if (strcmp(name, FM_FMRI_SCHEME_CPU) == 0) { 52331e37bb4Svn83148 uint32_t cpuid; 52431e37bb4Svn83148 52531e37bb4Svn83148 if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, 52631e37bb4Svn83148 &cpuid) == 0) 52731e37bb4Svn83148 ret = ldmsvcs_cpu_req_offline(lhp, cpuid); 52831e37bb4Svn83148 } else if (strcmp(name, FM_FMRI_SCHEME_MEM) == 0) { 52931e37bb4Svn83148 uint64_t pa; 53031e37bb4Svn83148 53131e37bb4Svn83148 if (nvlist_lookup_uint64(nvl, FM_FMRI_MEM_PHYSADDR, 53231e37bb4Svn83148 &pa) == 0) 53331e37bb4Svn83148 ret = ldmsvcs_mem_req_retire(lhp, pa); 53431e37bb4Svn83148 else 53531e37bb4Svn83148 ret = EINVAL; 53631e37bb4Svn83148 } 53731e37bb4Svn83148 return (ret); 53831e37bb4Svn83148 } 53931e37bb4Svn83148 } 54031e37bb4Svn83148 5415f149bcaScy152378 int 5425f149bcaScy152378 ldom_fmri_unretire(ldom_hdl_t *lhp, nvlist_t *nvl) 5435f149bcaScy152378 { 5445f149bcaScy152378 char *name; 5455f149bcaScy152378 int ret = ENOTSUP; 5465f149bcaScy152378 5475f149bcaScy152378 if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &name) != 0) 5485f149bcaScy152378 return (EINVAL); 54931e37bb4Svn83148 55031e37bb4Svn83148 /* 55125351652SVuong Nguyen * ldom_ldmd_is_up can only be true if a pri can be obtained from ldmd. 55231e37bb4Svn83148 */ 5535f149bcaScy152378 if (!ldom_ldmd_is_up) { 5545f149bcaScy152378 /* Zeus is unavail; use local routines for status/retire */ 5555f149bcaScy152378 5565f149bcaScy152378 if (strcmp(name, FM_FMRI_SCHEME_CPU) == 0) { 5575f149bcaScy152378 processorid_t vid; 5585f149bcaScy152378 uint32_t cpuid; 5595f149bcaScy152378 5605f149bcaScy152378 if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, &cpuid) 5615f149bcaScy152378 == 0 && (vid = cpu_phys2virt(lhp, cpuid)) != -1) 5625f149bcaScy152378 return (p_online(vid, P_ONLINE)); 5635f149bcaScy152378 } else if (strcmp(name, FM_FMRI_SCHEME_MEM) == 0) { 564e4b86885SCheng Sean Ye fmd_agent_hdl_t *hdl; 565e4b86885SCheng Sean Ye int err; 566e4b86885SCheng Sean Ye if ((hdl = fmd_agent_open(FMD_AGENT_VERSION)) == NULL) { 567e4b86885SCheng Sean Ye err = errno; 568e4b86885SCheng Sean Ye } else { 569e4b86885SCheng Sean Ye err = fmd_agent_page_unretire(hdl, nvl); 570e4b86885SCheng Sean Ye if (err == FMD_AGENT_RETIRE_DONE) 571e4b86885SCheng Sean Ye err = 0; 572e4b86885SCheng Sean Ye else 573e4b86885SCheng Sean Ye err = fmd_agent_errno(hdl); 574e4b86885SCheng Sean Ye fmd_agent_close(hdl); 575e4b86885SCheng Sean Ye } 576e4b86885SCheng Sean Ye return (err); 5775f149bcaScy152378 } 5785f149bcaScy152378 5795f149bcaScy152378 return (EINVAL); 5805f149bcaScy152378 } else { 5815f149bcaScy152378 /* Zeus is avail; use Zeus for status/retire */ 5825f149bcaScy152378 5835f149bcaScy152378 if (strcmp(name, FM_FMRI_SCHEME_CPU) == 0) { 5845f149bcaScy152378 uint32_t cpuid; 5855f149bcaScy152378 5865f149bcaScy152378 if (nvlist_lookup_uint32(nvl, FM_FMRI_CPU_ID, 5875f149bcaScy152378 &cpuid) == 0) 5885f149bcaScy152378 ret = ldmsvcs_cpu_req_online(lhp, cpuid); 5895f149bcaScy152378 } else if (strcmp(name, FM_FMRI_SCHEME_MEM) == 0) { 5905f149bcaScy152378 uint64_t pa; 5915f149bcaScy152378 5925f149bcaScy152378 if (nvlist_lookup_uint64(nvl, FM_FMRI_MEM_PHYSADDR, 5935f149bcaScy152378 &pa) == 0) 5945f149bcaScy152378 ret = ldmsvcs_mem_req_unretire(lhp, pa); 5955f149bcaScy152378 else 5965f149bcaScy152378 ret = EINVAL; 5975f149bcaScy152378 } 5985f149bcaScy152378 return (ret); 5995f149bcaScy152378 } 6005f149bcaScy152378 } 6015f149bcaScy152378 6025f149bcaScy152378 static int 6035f149bcaScy152378 fmri_blacklist(ldom_hdl_t *lhp, nvlist_t *nvl, int cmd) 60431e37bb4Svn83148 { 60531e37bb4Svn83148 char *name; 60625351652SVuong Nguyen uint32_t type = 0; 60731e37bb4Svn83148 60825351652SVuong Nguyen if ((ldom_get_type(lhp, &type) != 0) || 60925351652SVuong Nguyen ((type & LDOM_TYPE_LEGACY) == 0)) 61031e37bb4Svn83148 return (0); 61131e37bb4Svn83148 61231e37bb4Svn83148 if (nvlist_lookup_string(nvl, FM_FMRI_SCHEME, &name) != 0) 61331e37bb4Svn83148 return (EINVAL); 61431e37bb4Svn83148 61531e37bb4Svn83148 if (strcmp(name, FM_FMRI_SCHEME_CPU) == 0) { 61631e37bb4Svn83148 bl_req_t blr; 61731e37bb4Svn83148 char *class; 61831e37bb4Svn83148 int fd, rc, err; 61931e37bb4Svn83148 62031e37bb4Svn83148 if ((nvlist_lookup_string(nvl, FM_CLASS, &class) != 0) || 62131e37bb4Svn83148 (class == NULL) || (*class == '\0')) 62231e37bb4Svn83148 return (EINVAL); 62331e37bb4Svn83148 62431e37bb4Svn83148 if ((fd = open("/dev/bl", O_RDONLY)) < 0) 62531e37bb4Svn83148 return (EIO); 62631e37bb4Svn83148 62731e37bb4Svn83148 if (nvlist_size(nvl, &blr.bl_fmrisz, NV_ENCODE_NATIVE) != 0 || 62831e37bb4Svn83148 blr.bl_fmrisz == 0 || 62931e37bb4Svn83148 (blr.bl_fmri = (caddr_t)lhp->allocp(blr.bl_fmrisz)) == 63031e37bb4Svn83148 NULL) { 63131e37bb4Svn83148 (void) close(fd); 63231e37bb4Svn83148 return (EINVAL); 63331e37bb4Svn83148 } 63431e37bb4Svn83148 63531e37bb4Svn83148 blr.bl_class = class; 63631e37bb4Svn83148 6375f149bcaScy152378 rc = ioctl(fd, cmd, &blr); 63831e37bb4Svn83148 err = errno; 63931e37bb4Svn83148 64031e37bb4Svn83148 lhp->freep((void *)&blr.bl_fmri, blr.bl_fmrisz); 64131e37bb4Svn83148 (void) close(fd); 64231e37bb4Svn83148 64331e37bb4Svn83148 if (rc < 0 && err != ENOTSUP) { 64431e37bb4Svn83148 errno = err; 64531e37bb4Svn83148 return (-1); 64631e37bb4Svn83148 } 64731e37bb4Svn83148 } 64831e37bb4Svn83148 64931e37bb4Svn83148 return (0); 65031e37bb4Svn83148 } 65131e37bb4Svn83148 6525f149bcaScy152378 /* 6535f149bcaScy152378 * blacklist cpus in a non-LDOMS environment 6545f149bcaScy152378 */ 6555f149bcaScy152378 int 6565f149bcaScy152378 ldom_fmri_blacklist(ldom_hdl_t *lhp, nvlist_t *nvl) 6575f149bcaScy152378 { 6585f149bcaScy152378 return (fmri_blacklist(lhp, nvl, BLIOC_INSERT)); 6595f149bcaScy152378 } 6605f149bcaScy152378 6615f149bcaScy152378 /* 6625f149bcaScy152378 * unblacklist cpus 6635f149bcaScy152378 */ 6645f149bcaScy152378 int 6655f149bcaScy152378 ldom_fmri_unblacklist(ldom_hdl_t *lhp, nvlist_t *nvl) 6665f149bcaScy152378 { 6675f149bcaScy152378 return (fmri_blacklist(lhp, nvl, BLIOC_DELETE)); 6685f149bcaScy152378 } 6695f149bcaScy152378 67031e37bb4Svn83148 67131e37bb4Svn83148 ssize_t 67225351652SVuong Nguyen ldom_get_local_md(ldom_hdl_t *lhp, uint64_t **buf) 67325351652SVuong Nguyen { 67425351652SVuong Nguyen return (get_local_core_md(lhp, buf)); 67525351652SVuong Nguyen } 67625351652SVuong Nguyen 67725351652SVuong Nguyen ssize_t 67831e37bb4Svn83148 ldom_get_core_md(ldom_hdl_t *lhp, uint64_t **buf) 67931e37bb4Svn83148 { 680ef884685Srb144127 ssize_t rv; /* return value */ 681c3b50bc5Srb144127 uint64_t tok; /* opaque PRI token */ 68225351652SVuong Nguyen uint32_t type = 0; 683ef884685Srb144127 684*c95876f5SVuong Nguyen if (ldom_get_type(lhp, &type) != 0) { 68525351652SVuong Nguyen return (-1); 68625351652SVuong Nguyen } 687*c95876f5SVuong Nguyen 68825351652SVuong Nguyen if ((type & LDOM_TYPE_CONTROL) != 0) { 68925351652SVuong Nguyen /* Get the pri from Zeus first. If failed, get it from libpri */ 690c3b50bc5Srb144127 if ((rv = ldmsvcs_get_core_md(lhp, buf)) < 1) { 691c3b50bc5Srb144127 (void) pthread_mutex_lock(&ldom_pri_lock); 692c3b50bc5Srb144127 rv = ldom_pri_get(PRI_GET, &tok, 693c3b50bc5Srb144127 buf, lhp->allocp, lhp->freep); 694c3b50bc5Srb144127 (void) pthread_mutex_unlock(&ldom_pri_lock); 695ef884685Srb144127 } else { 696c3b50bc5Srb144127 ldom_ldmd_is_up = 1; 69725351652SVuong Nguyen xmpp_start(); 698ef884685Srb144127 } 699c3b50bc5Srb144127 } else { 700*c95876f5SVuong Nguyen /* get the pruned PRI from the libpri */ 701*c95876f5SVuong Nguyen (void) pthread_mutex_lock(&ldom_pri_lock); 702*c95876f5SVuong Nguyen rv = ldom_pri_get(PRI_GET, &tok, buf, lhp->allocp, lhp->freep); 703*c95876f5SVuong Nguyen (void) pthread_mutex_unlock(&ldom_pri_lock); 704c3b50bc5Srb144127 } 70531e37bb4Svn83148 706c3b50bc5Srb144127 return (rv); 70731e37bb4Svn83148 } 70831e37bb4Svn83148 70931e37bb4Svn83148 int 71025351652SVuong Nguyen ldom_find_id(ldom_hdl_t *lhp, uint64_t addr, ldom_rsrc_t rsrc, 71125351652SVuong Nguyen uint64_t *virt_addr, char *name, int name_size, uint64_t *did) 71231e37bb4Svn83148 { 71325351652SVuong Nguyen uint32_t type = 0; 71431e37bb4Svn83148 71525351652SVuong Nguyen (void) ldom_get_type(lhp, &type); 71625351652SVuong Nguyen if ((type & LDOM_TYPE_CONTROL) == 0) { 71725351652SVuong Nguyen return (ENOTSUP); 71825351652SVuong Nguyen } 71925351652SVuong Nguyen if (!ldom_ldmd_is_up) { 72025351652SVuong Nguyen return (EAGAIN); 72125351652SVuong Nguyen } 72225351652SVuong Nguyen return (ldmsvcs_io_req_id(lhp, addr, rsrc, virt_addr, 72325351652SVuong Nguyen name, name_size, did)); 72425351652SVuong Nguyen } 72525351652SVuong Nguyen 72625351652SVuong Nguyen int 72725351652SVuong Nguyen ldom_register_event(ldom_hdl_t *lhp, ldom_reg_cb_t cb, ldom_cb_arg_t data) 72825351652SVuong Nguyen { 72925351652SVuong Nguyen uint32_t type = 0; 73025351652SVuong Nguyen 73125351652SVuong Nguyen (void) ldom_get_type(lhp, &type); 73225351652SVuong Nguyen if ((type & LDOM_TYPE_CONTROL) == 0) { 73325351652SVuong Nguyen return (ENOTSUP); 73425351652SVuong Nguyen } 73525351652SVuong Nguyen 73625351652SVuong Nguyen return (xmpp_add_client(lhp, cb, data)); 73725351652SVuong Nguyen } 73825351652SVuong Nguyen 73925351652SVuong Nguyen int 74025351652SVuong Nguyen ldom_unregister_event(ldom_hdl_t *lhp) 74125351652SVuong Nguyen { 74225351652SVuong Nguyen uint32_t type = 0; 74325351652SVuong Nguyen 74425351652SVuong Nguyen (void) ldom_get_type(lhp, &type); 74525351652SVuong Nguyen if ((type & LDOM_TYPE_CONTROL) == 0) { 74625351652SVuong Nguyen return (ENOTSUP); 74725351652SVuong Nguyen } 74825351652SVuong Nguyen 74925351652SVuong Nguyen return (xmpp_remove_client(lhp)); 75031e37bb4Svn83148 } 75131e37bb4Svn83148 75231e37bb4Svn83148 /* 75325351652SVuong Nguyen * ldom_init() 75425351652SVuong Nguyen * Description: 75525351652SVuong Nguyen * Return a libldom handle to the caller for uniquely identify the session 75625351652SVuong Nguyen * betweem the caller and the libldom.so. The handle is used in 75725351652SVuong Nguyen * subsequent calls into the libldom.so 75825351652SVuong Nguyen * 75925351652SVuong Nguyen * If the caller does not provide a alloc()/free(), the libldom uses its 76025351652SVuong Nguyen * own functions. 76131e37bb4Svn83148 */ 76231e37bb4Svn83148 ldom_hdl_t * 76331e37bb4Svn83148 ldom_init(void *(*allocp)(size_t size), 76431e37bb4Svn83148 void (*freep)(void *addr, size_t size)) 76531e37bb4Svn83148 { 76631e37bb4Svn83148 struct ldom_hdl *lhp; 76731e37bb4Svn83148 76825351652SVuong Nguyen if (allocp == NULL && freep == NULL) { 76925351652SVuong Nguyen allocp = ldom_alloc; 77025351652SVuong Nguyen freep = ldom_free; 77125351652SVuong Nguyen } else if (allocp == NULL || freep == NULL) { 77225351652SVuong Nguyen /* missing alloc or free functions */ 77325351652SVuong Nguyen return (NULL); 77425351652SVuong Nguyen } 77525351652SVuong Nguyen 776c3b50bc5Srb144127 (void) pthread_mutex_lock(&ldom_pri_lock); 77731e37bb4Svn83148 778c3b50bc5Srb144127 if (ldom_pri_init() < 0) { 779c3b50bc5Srb144127 (void) pthread_mutex_unlock(&ldom_pri_lock); 780ef884685Srb144127 return (NULL); 781ef884685Srb144127 } 782ef884685Srb144127 783c3b50bc5Srb144127 if ((lhp = allocp(sizeof (struct ldom_hdl))) == NULL) { 784c3b50bc5Srb144127 ldom_pri_fini(); 785c3b50bc5Srb144127 (void) pthread_mutex_unlock(&ldom_pri_lock); 786c3b50bc5Srb144127 return (NULL); 787c3b50bc5Srb144127 } 788c3b50bc5Srb144127 789c3b50bc5Srb144127 (void) pthread_mutex_unlock(&ldom_pri_lock); 790c3b50bc5Srb144127 79131e37bb4Svn83148 lhp->allocp = allocp; 79231e37bb4Svn83148 lhp->freep = freep; 79331e37bb4Svn83148 79431e37bb4Svn83148 ldmsvcs_init(lhp); 79531e37bb4Svn83148 79631e37bb4Svn83148 return (lhp); 79731e37bb4Svn83148 } 79831e37bb4Svn83148 79931e37bb4Svn83148 80031e37bb4Svn83148 void 80131e37bb4Svn83148 ldom_fini(ldom_hdl_t *lhp) 80231e37bb4Svn83148 { 80331e37bb4Svn83148 if (lhp == NULL) 80431e37bb4Svn83148 return; 80531e37bb4Svn83148 80625351652SVuong Nguyen (void) xmpp_remove_client(lhp); 80731e37bb4Svn83148 ldmsvcs_fini(lhp); 80831e37bb4Svn83148 lhp->freep(lhp, sizeof (struct ldom_hdl)); 809ef884685Srb144127 810c3b50bc5Srb144127 (void) pthread_mutex_lock(&ldom_pri_lock); 811c3b50bc5Srb144127 812c3b50bc5Srb144127 ldom_pri_fini(); 813c3b50bc5Srb144127 814c3b50bc5Srb144127 (void) pthread_mutex_unlock(&ldom_pri_lock); 81531e37bb4Svn83148 } 81631e37bb4Svn83148 81731e37bb4Svn83148 /* end file */ 818