1843e1988Sjohnlev /* 2843e1988Sjohnlev * CDDL HEADER START 3843e1988Sjohnlev * 4843e1988Sjohnlev * The contents of this file are subject to the terms of the 5843e1988Sjohnlev * Common Development and Distribution License (the "License"). 6843e1988Sjohnlev * You may not use this file except in compliance with the License. 7843e1988Sjohnlev * 8843e1988Sjohnlev * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9843e1988Sjohnlev * or http://www.opensolaris.org/os/licensing. 10843e1988Sjohnlev * See the License for the specific language governing permissions 11843e1988Sjohnlev * and limitations under the License. 12843e1988Sjohnlev * 13843e1988Sjohnlev * When distributing Covered Code, include this CDDL HEADER in each 14843e1988Sjohnlev * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15843e1988Sjohnlev * If applicable, add the following below this CDDL HEADER, with the 16843e1988Sjohnlev * fields enclosed by brackets "[]" replaced with your own identifying 17843e1988Sjohnlev * information: Portions Copyright [yyyy] [name of copyright owner] 18843e1988Sjohnlev * 19843e1988Sjohnlev * CDDL HEADER END 20843e1988Sjohnlev */ 21843e1988Sjohnlev 22843e1988Sjohnlev /* 23613b2871SRichard Bean * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24843e1988Sjohnlev * Use is subject to license terms. 25843e1988Sjohnlev */ 26843e1988Sjohnlev 27843e1988Sjohnlev /* 28843e1988Sjohnlev * This rather uninspiring device enables userland to discover if 29843e1988Sjohnlev * the current kernel is actually a dom0 or other domain e.g. domU. 30843e1988Sjohnlev */ 31843e1988Sjohnlev 32843e1988Sjohnlev #include <sys/types.h> 33843e1988Sjohnlev #include <sys/file.h> 34843e1988Sjohnlev #include <sys/errno.h> 35843e1988Sjohnlev #include <sys/open.h> 36843e1988Sjohnlev #include <sys/cred.h> 37843e1988Sjohnlev #include <sys/conf.h> 38843e1988Sjohnlev #include <sys/stat.h> 39843e1988Sjohnlev #include <sys/modctl.h> 40843e1988Sjohnlev #include <sys/ddi.h> 41843e1988Sjohnlev #include <sys/sunddi.h> 42843e1988Sjohnlev #include <sys/hypervisor.h> 43843e1988Sjohnlev #include <sys/sysmacros.h> 44843e1988Sjohnlev 45843e1988Sjohnlev #include <sys/domcaps_impl.h> 46843e1988Sjohnlev 47843e1988Sjohnlev static dev_info_t *domcaps_devi; 48843e1988Sjohnlev 49843e1988Sjohnlev /*ARGSUSED*/ 50843e1988Sjohnlev static int 51843e1988Sjohnlev domcaps_getinfo(dev_info_t *devi, ddi_info_cmd_t cmd, void *arg, void **result) 52843e1988Sjohnlev { 53843e1988Sjohnlev if (getminor((dev_t)arg) != DOMCAPS_MINOR) 54843e1988Sjohnlev return (DDI_FAILURE); 55843e1988Sjohnlev 56843e1988Sjohnlev switch (cmd) { 57843e1988Sjohnlev case DDI_INFO_DEVT2DEVINFO: 58843e1988Sjohnlev *result = domcaps_devi; 59843e1988Sjohnlev break; 60843e1988Sjohnlev case DDI_INFO_DEVT2INSTANCE: 61843e1988Sjohnlev *result = 0; 62843e1988Sjohnlev break; 63843e1988Sjohnlev default: 64843e1988Sjohnlev return (DDI_FAILURE); 65843e1988Sjohnlev } 66843e1988Sjohnlev 67843e1988Sjohnlev return (DDI_SUCCESS); 68843e1988Sjohnlev } 69843e1988Sjohnlev 70843e1988Sjohnlev static int 71843e1988Sjohnlev domcaps_attach(dev_info_t *devi, ddi_attach_cmd_t cmd) 72843e1988Sjohnlev { 73843e1988Sjohnlev if (cmd != DDI_ATTACH) 74843e1988Sjohnlev return (DDI_FAILURE); 75843e1988Sjohnlev 76843e1988Sjohnlev if (ddi_create_minor_node(devi, ddi_get_name(devi), S_IFCHR, 77843e1988Sjohnlev ddi_get_instance(devi), DDI_PSEUDO, 0) != DDI_SUCCESS) 78843e1988Sjohnlev return (DDI_FAILURE); 79843e1988Sjohnlev 80843e1988Sjohnlev domcaps_devi = devi; 81843e1988Sjohnlev ddi_report_dev(devi); 82843e1988Sjohnlev return (DDI_SUCCESS); 83843e1988Sjohnlev } 84843e1988Sjohnlev 85843e1988Sjohnlev static int 86843e1988Sjohnlev domcaps_detach(dev_info_t *devi, ddi_detach_cmd_t cmd) 87843e1988Sjohnlev { 88843e1988Sjohnlev if (cmd != DDI_DETACH) 89843e1988Sjohnlev return (DDI_FAILURE); 90843e1988Sjohnlev ddi_remove_minor_node(devi, NULL); 91843e1988Sjohnlev domcaps_devi = NULL; 92843e1988Sjohnlev return (DDI_SUCCESS); 93843e1988Sjohnlev } 94843e1988Sjohnlev 95843e1988Sjohnlev /*ARGSUSED1*/ 96843e1988Sjohnlev static int 97843e1988Sjohnlev domcaps_open(dev_t *dev, int flag, int otyp, cred_t *cr) 98843e1988Sjohnlev { 99843e1988Sjohnlev return (getminor(*dev) == DOMCAPS_MINOR ? 0 : ENXIO); 100843e1988Sjohnlev } 101843e1988Sjohnlev 102843e1988Sjohnlev /*ARGSUSED*/ 103843e1988Sjohnlev static int 104843e1988Sjohnlev domcaps_read(dev_t dev, uio_t *uio, cred_t *cr) 105843e1988Sjohnlev { 106843e1988Sjohnlev if (DOMAIN_IS_INITDOMAIN(xen_info)) { 107843e1988Sjohnlev static char data[] = "control_d\n"; 108843e1988Sjohnlev size_t nbytes; 109843e1988Sjohnlev 110843e1988Sjohnlev if (uio->uio_loffset > sizeof (data)) 111843e1988Sjohnlev return (0); 112843e1988Sjohnlev nbytes = MIN(uio->uio_resid, sizeof (data) - uio->uio_loffset); 113843e1988Sjohnlev 114843e1988Sjohnlev return (uiomove(data + uio->uio_loffset, nbytes, 115843e1988Sjohnlev UIO_READ, uio)); 116843e1988Sjohnlev } 117843e1988Sjohnlev 118843e1988Sjohnlev return (0); 119843e1988Sjohnlev } 120843e1988Sjohnlev 121843e1988Sjohnlev static struct cb_ops domcaps_cb_ops = { 122843e1988Sjohnlev domcaps_open, 123843e1988Sjohnlev nulldev, /* close */ 124843e1988Sjohnlev nodev, /* strategy */ 125843e1988Sjohnlev nodev, /* print */ 126843e1988Sjohnlev nodev, /* dump */ 127843e1988Sjohnlev domcaps_read, 128843e1988Sjohnlev nodev, /* write */ 129843e1988Sjohnlev nodev, /* ioctl */ 130843e1988Sjohnlev nodev, /* devmap */ 131843e1988Sjohnlev nodev, /* mmap */ 132843e1988Sjohnlev nodev, /* segmap */ 133843e1988Sjohnlev nochpoll, /* poll */ 134843e1988Sjohnlev ddi_prop_op, 135843e1988Sjohnlev NULL, 136843e1988Sjohnlev D_64BIT | D_MP, 137843e1988Sjohnlev CB_REV, 138843e1988Sjohnlev NULL, 139843e1988Sjohnlev NULL 140843e1988Sjohnlev }; 141843e1988Sjohnlev 142843e1988Sjohnlev static struct dev_ops domcaps_dv_ops = { 143843e1988Sjohnlev DEVO_REV, 144843e1988Sjohnlev 0, 145843e1988Sjohnlev domcaps_getinfo, 146843e1988Sjohnlev nulldev, /* identify */ 147843e1988Sjohnlev nulldev, /* probe */ 148843e1988Sjohnlev domcaps_attach, 149843e1988Sjohnlev domcaps_detach, 150843e1988Sjohnlev nodev, /* reset */ 151843e1988Sjohnlev &domcaps_cb_ops, 152843e1988Sjohnlev NULL, /* struct bus_ops */ 153*19397407SSherry Moore NULL, /* power */ 154*19397407SSherry Moore ddi_quiesce_not_needed, /* quiesce */ 155843e1988Sjohnlev }; 156843e1988Sjohnlev 157843e1988Sjohnlev static struct modldrv modldrv = { 158843e1988Sjohnlev &mod_driverops, 159613b2871SRichard Bean "hypervisor capabilities driver", 160843e1988Sjohnlev &domcaps_dv_ops 161843e1988Sjohnlev }; 162843e1988Sjohnlev 163843e1988Sjohnlev static struct modlinkage modl = { 164843e1988Sjohnlev MODREV_1, 165843e1988Sjohnlev { 166843e1988Sjohnlev (void *)&modldrv, 167843e1988Sjohnlev NULL /* null termination */ 168843e1988Sjohnlev } 169843e1988Sjohnlev }; 170843e1988Sjohnlev 171843e1988Sjohnlev int 172843e1988Sjohnlev _init(void) 173843e1988Sjohnlev { 174843e1988Sjohnlev return (mod_install(&modl)); 175843e1988Sjohnlev } 176843e1988Sjohnlev 177843e1988Sjohnlev int 178843e1988Sjohnlev _fini(void) 179843e1988Sjohnlev { 180843e1988Sjohnlev return (mod_remove(&modl)); 181843e1988Sjohnlev } 182843e1988Sjohnlev 183843e1988Sjohnlev int 184843e1988Sjohnlev _info(struct modinfo *modinfo) 185843e1988Sjohnlev { 186843e1988Sjohnlev return (mod_info(&modl, modinfo)); 187843e1988Sjohnlev } 188