summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/xen/io/xpvd.c
diff options
context:
space:
mode:
authormrj <none@none>2007-12-21 14:13:23 -0800
committermrj <none@none>2007-12-21 14:13:23 -0800
commit551bc2a66868b5cb5be6b70ab9f55515e77a39a9 (patch)
treea01e761c9864ea9483c468ced858a0f67edcbf93 /usr/src/uts/common/xen/io/xpvd.c
parent71a79fe7afa36dcf0de6902c2c6ef432980534d3 (diff)
downloadillumos-joyent-551bc2a66868b5cb5be6b70ab9f55515e77a39a9.tar.gz
PSARC 2007/664 Paravirtualized Drivers for Fully Virtualized xVM Domains
6525093 xnb/xnf should use hypervisor based copy for xnb->xnf data path 6608917 members of struct xnf and xnb need unique names 6609324 deadlock trying to own the HAT migrate lock 6609805 still missing XPV_DISALLOW_MIGRATE/XPV_ALLOW_MIGRATE bracketing in hat_i86.c 6616384 xnb's grant ref unmapping is inefficient 6619947 Solaris should provide a PV network driver for xVM HVM environments 6632774 panic setting up xen console --HG-- rename : usr/src/uts/i86xpv/os/gnttab.c => usr/src/uts/common/xen/os/gnttab.c rename : usr/src/uts/i86xpv/os/hypercall.c => usr/src/uts/common/xen/os/hypercall.c rename : usr/src/uts/i86xpv/sys/gnttab.h => usr/src/uts/common/xen/sys/gnttab.h rename : usr/src/uts/i86xpv/ml/hypersubr.s => usr/src/uts/intel/ia32/ml/hypersubr.s rename : usr/src/uts/i86xpv/sys/hypervisor.h => usr/src/uts/intel/sys/hypervisor.h rename : usr/src/uts/i86xpv/sys/xen_errno.h => usr/src/uts/intel/sys/xen_errno.h
Diffstat (limited to 'usr/src/uts/common/xen/io/xpvd.c')
-rw-r--r--usr/src/uts/common/xen/io/xpvd.c96
1 files changed, 88 insertions, 8 deletions
diff --git a/usr/src/uts/common/xen/io/xpvd.c b/usr/src/uts/common/xen/io/xpvd.c
index c989960444..34408e16f8 100644
--- a/usr/src/uts/common/xen/io/xpvd.c
+++ b/usr/src/uts/common/xen/io/xpvd.c
@@ -36,7 +36,6 @@
*/
#include <sys/conf.h>
-#include <sys/hypervisor.h>
#include <sys/kmem.h>
#include <sys/debug.h>
#include <sys/modctl.h>
@@ -46,18 +45,29 @@
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/sunndi.h>
-#include <sys/mach_intr.h>
-#include <sys/evtchn_impl.h>
#include <sys/avintr.h>
#include <sys/psm.h>
#include <sys/spl.h>
#include <sys/promif.h>
#include <sys/list.h>
-#include <sys/xen_mmu.h>
#include <sys/bootconf.h>
#include <sys/bootsvcs.h>
-#include <sys/bootinfo.h>
#include <util/sscanf.h>
+#include <sys/mach_intr.h>
+#include <sys/bootinfo.h>
+#ifdef XPV_HVM_DRIVER
+#include <sys/xpv_support.h>
+#include <sys/hypervisor.h>
+#include <sys/archsystm.h>
+#include <sys/cpu.h>
+#include <public/xen.h>
+#include <public/event_channel.h>
+#include <public/io/xenbus.h>
+#else
+#include <sys/hypervisor.h>
+#include <sys/evtchn_impl.h>
+#include <sys/xen_mmu.h>
+#endif
#include <xen/sys/xenbus_impl.h>
#include <xen/sys/xendev.h>
@@ -173,6 +183,10 @@ static ndi_event_set_t xpvd_ndi_events = {
static ndi_event_hdl_t xpvd_ndi_event_handle;
+#ifdef XPV_HVM_DRIVER
+static int hvm_vdev_num[26];
+#endif
+
/*
* Hypervisor interrupt capabilities
*/
@@ -236,7 +250,16 @@ static int
xpvd_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
{
extern void xvdi_watch_devices(int);
- xpvd_dip = devi;
+
+#ifdef XPV_HVM_DRIVER
+ if (xen_info == NULL) {
+ if (ddi_hold_installed_driver(ddi_name_to_major("xpv")) ==
+ NULL) {
+ cmn_err(CE_WARN, "Couldn't initialize xpv framework");
+ return (DDI_FAILURE);
+ }
+ }
+#endif
if (ndi_event_alloc_hdl(devi, 0, &xpvd_ndi_event_handle,
NDI_SLEEP) != NDI_SUCCESS) {
@@ -256,6 +279,7 @@ xpvd_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
else
xvdi_watch_devices(XENSTORE_UP);
+ xpvd_dip = devi;
ddi_report_dev(devi);
return (DDI_SUCCESS);
@@ -557,6 +581,9 @@ xpvd_intr_ops(dev_info_t *pdip, dev_info_t *rdip, ddi_intr_op_t intr_op,
case DDI_INTROP_SETMASK:
case DDI_INTROP_CLRMASK:
+#ifdef XPV_HVM_DRIVER
+ return (DDI_ENOTSUP);
+#else
/*
* Handle this here
*/
@@ -568,14 +595,18 @@ xpvd_intr_ops(dev_info_t *pdip, dev_info_t *rdip, ddi_intr_op_t intr_op,
ec_enable_irq(hdlp->ih_vector);
}
break;
-
+#endif
case DDI_INTROP_GETPENDING:
+#ifdef XPV_HVM_DRIVER
+ return (DDI_ENOTSUP);
+#else
if (hdlp->ih_type != DDI_INTR_TYPE_FIXED)
return (DDI_FAILURE);
*(int *)result = ec_pending_irq(hdlp->ih_vector);
DDI_INTR_NEXDBG((CE_CONT, "xpvd: GETPENDING returned = %x\n",
*(int *)result));
break;
+#endif
case DDI_INTROP_NAVAIL:
*(int *)result = 1;
@@ -689,6 +720,11 @@ xpvd_name_child(dev_info_t *child, char *name, int namelen)
int *domain, *vdev;
uint_t ndomain, nvdev;
char *unit_address;
+ int devno;
+#ifdef XPV_HVM_DRIVER
+ char *xip;
+ int xenstore_id;
+#endif
/*
* i_xpvd_parse_devname() knows the formats used by this
@@ -721,11 +757,45 @@ xpvd_name_child(dev_info_t *child, char *name, int namelen)
/*
* Use "unit-address" property (frontend/softdev drivers).
+ *
+ * For PV domains, the disk name should be a simple number. In an
+ * HVM domain, it will be a string of the form hdX. In the latter
+ * case we convert hda to 0, hdb to 1, and so on.
*/
if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
DDI_PROP_DONTPASS, "unit-address", &unit_address)
== DDI_PROP_SUCCESS) {
- (void) snprintf(name, namelen, "%s", unit_address);
+ devno = -1;
+ if (unit_address[0] >= '0' && unit_address[0] <= '9')
+ (void) sscanf(unit_address, "%d", &devno);
+#ifdef XPV_HVM_DRIVER
+ /*
+ * XXX: we should really check the device class here. We
+ * always want to set hvm_vdev_num[] - even if we somehow
+ * end up with a non-hdX device name.
+ */
+ else if (strlen(unit_address) == 3 &&
+ unit_address[0] == 'h' && unit_address[1] == 'd') {
+ devno = unit_address[2] - 'a';
+ if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
+ DDI_PROP_DONTPASS, "xenstore-id", &xip)
+ == DDI_PROP_SUCCESS) {
+ (void) sscanf(xip, "%d", &xenstore_id);
+ ddi_prop_free(xip);
+ hvm_vdev_num[devno] = xenstore_id;
+ } else {
+ devno = -1;
+ }
+ }
+#endif
+
+ if (devno < 0) {
+ cmn_err(CE_WARN, "Unrecognized device: %s",
+ unit_address);
+ ddi_prop_free(unit_address);
+ return (DDI_FAILURE);
+ }
+ (void) snprintf(name, namelen, "%x", devno);
ddi_prop_free(unit_address);
return (DDI_SUCCESS);
}
@@ -846,10 +916,20 @@ i_xpvd_parse_devname(char *name, xendev_devclass_t *devclassp,
/* Frontend format is "<vdev>". */
*domp = DOMID_SELF;
if (sscanf(caddr, "%x", vdevp) == 1) {
+#ifdef XPV_HVM_DRIVER
+ if (*devclassp == XEN_VBLK) {
+ if (*vdevp < 0 || *vdevp > 26) {
+ *vdevp = -1;
+ goto done;
+ }
+ *vdevp = hvm_vdev_num[*vdevp];
+ }
+#endif
ret = B_TRUE;
goto done;
}
+
done:
kmem_free(device_name, len);
return (ret);