xpvd.c (843e1988) xpvd.c (551bc2a6)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 22 unchanged lines hidden (view full) ---

31 *
32 * TODO:
33 * - Add watchpoints on vbd/vif and enumerate/offline on watch callback
34 * - Add DR IOCTLs
35 * - Filter/restrict property lookups into xenstore
36 */
37
38#include <sys/conf.h>
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE

--- 22 unchanged lines hidden (view full) ---

31 *
32 * TODO:
33 * - Add watchpoints on vbd/vif and enumerate/offline on watch callback
34 * - Add DR IOCTLs
35 * - Filter/restrict property lookups into xenstore
36 */
37
38#include <sys/conf.h>
39#include <sys/hypervisor.h>
40#include <sys/kmem.h>
41#include <sys/debug.h>
42#include <sys/modctl.h>
43#include <sys/autoconf.h>
44#include <sys/ddi_impldefs.h>
45#include <sys/ddi_subrdefs.h>
46#include <sys/ddi.h>
47#include <sys/sunddi.h>
48#include <sys/sunndi.h>
39#include <sys/kmem.h>
40#include <sys/debug.h>
41#include <sys/modctl.h>
42#include <sys/autoconf.h>
43#include <sys/ddi_impldefs.h>
44#include <sys/ddi_subrdefs.h>
45#include <sys/ddi.h>
46#include <sys/sunddi.h>
47#include <sys/sunndi.h>
49#include <sys/mach_intr.h>
50#include <sys/evtchn_impl.h>
51#include <sys/avintr.h>
52#include <sys/psm.h>
53#include <sys/spl.h>
54#include <sys/promif.h>
55#include <sys/list.h>
48#include <sys/avintr.h>
49#include <sys/psm.h>
50#include <sys/spl.h>
51#include <sys/promif.h>
52#include <sys/list.h>
56#include <sys/xen_mmu.h>
57#include <sys/bootconf.h>
58#include <sys/bootsvcs.h>
53#include <sys/bootconf.h>
54#include <sys/bootsvcs.h>
59#include <sys/bootinfo.h>
60#include <util/sscanf.h>
55#include <util/sscanf.h>
56#include <sys/mach_intr.h>
57#include <sys/bootinfo.h>
58#ifdef XPV_HVM_DRIVER
59#include <sys/xpv_support.h>
60#include <sys/hypervisor.h>
61#include <sys/archsystm.h>
62#include <sys/cpu.h>
63#include <public/xen.h>
64#include <public/event_channel.h>
65#include <public/io/xenbus.h>
66#else
67#include <sys/hypervisor.h>
68#include <sys/evtchn_impl.h>
69#include <sys/xen_mmu.h>
70#endif
61#include <xen/sys/xenbus_impl.h>
62#include <xen/sys/xendev.h>
63
64/*
65 * DDI dev_ops entrypoints
66 */
67static int xpvd_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
68static int xpvd_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);

--- 99 unchanged lines hidden (view full) ---

168 (sizeof (xpvd_ndi_event_defs) / sizeof (xpvd_ndi_event_defs[0]))
169
170static ndi_event_set_t xpvd_ndi_events = {
171 NDI_EVENTS_REV1, XENDEV_N_NDI_EVENTS, xpvd_ndi_event_defs
172};
173
174static ndi_event_hdl_t xpvd_ndi_event_handle;
175
71#include <xen/sys/xenbus_impl.h>
72#include <xen/sys/xendev.h>
73
74/*
75 * DDI dev_ops entrypoints
76 */
77static int xpvd_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
78static int xpvd_attach(dev_info_t *devi, ddi_attach_cmd_t cmd);

--- 99 unchanged lines hidden (view full) ---

178 (sizeof (xpvd_ndi_event_defs) / sizeof (xpvd_ndi_event_defs[0]))
179
180static ndi_event_set_t xpvd_ndi_events = {
181 NDI_EVENTS_REV1, XENDEV_N_NDI_EVENTS, xpvd_ndi_event_defs
182};
183
184static ndi_event_hdl_t xpvd_ndi_event_handle;
185
186#ifdef XPV_HVM_DRIVER
187static int hvm_vdev_num[26];
188#endif
189
176/*
177 * Hypervisor interrupt capabilities
178 */
179#define XENDEV_INTR_CAPABILITIES \
180 (DDI_INTR_FLAG_EDGE | DDI_INTR_FLAG_MASKABLE | DDI_INTR_FLAG_PENDING)
181
182/*
183 * Module linkage information for the kernel.

--- 47 unchanged lines hidden (view full) ---

231 }
232}
233
234/*ARGSUSED*/
235static int
236xpvd_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
237{
238 extern void xvdi_watch_devices(int);
190/*
191 * Hypervisor interrupt capabilities
192 */
193#define XENDEV_INTR_CAPABILITIES \
194 (DDI_INTR_FLAG_EDGE | DDI_INTR_FLAG_MASKABLE | DDI_INTR_FLAG_PENDING)
195
196/*
197 * Module linkage information for the kernel.

--- 47 unchanged lines hidden (view full) ---

245 }
246}
247
248/*ARGSUSED*/
249static int
250xpvd_attach(dev_info_t *devi, ddi_attach_cmd_t cmd)
251{
252 extern void xvdi_watch_devices(int);
239 xpvd_dip = devi;
240
253
254#ifdef XPV_HVM_DRIVER
255 if (xen_info == NULL) {
256 if (ddi_hold_installed_driver(ddi_name_to_major("xpv")) ==
257 NULL) {
258 cmn_err(CE_WARN, "Couldn't initialize xpv framework");
259 return (DDI_FAILURE);
260 }
261 }
262#endif
263
241 if (ndi_event_alloc_hdl(devi, 0, &xpvd_ndi_event_handle,
242 NDI_SLEEP) != NDI_SUCCESS) {
243 xpvd_dip = NULL;
244 return (DDI_FAILURE);
245 }
246 if (ndi_event_bind_set(xpvd_ndi_event_handle, &xpvd_ndi_events,
247 NDI_SLEEP) != NDI_SUCCESS) {
248 (void) ndi_event_free_hdl(xpvd_ndi_event_handle);
249 xpvd_dip = NULL;
250 return (DDI_FAILURE);
251 }
252
253 /* watch both frontend and backend for new devices */
254 if (DOMAIN_IS_INITDOMAIN(xen_info))
255 (void) xs_register_xenbus_callback(xvdi_watch_devices);
256 else
257 xvdi_watch_devices(XENSTORE_UP);
258
264 if (ndi_event_alloc_hdl(devi, 0, &xpvd_ndi_event_handle,
265 NDI_SLEEP) != NDI_SUCCESS) {
266 xpvd_dip = NULL;
267 return (DDI_FAILURE);
268 }
269 if (ndi_event_bind_set(xpvd_ndi_event_handle, &xpvd_ndi_events,
270 NDI_SLEEP) != NDI_SUCCESS) {
271 (void) ndi_event_free_hdl(xpvd_ndi_event_handle);
272 xpvd_dip = NULL;
273 return (DDI_FAILURE);
274 }
275
276 /* watch both frontend and backend for new devices */
277 if (DOMAIN_IS_INITDOMAIN(xen_info))
278 (void) xs_register_xenbus_callback(xvdi_watch_devices);
279 else
280 xvdi_watch_devices(XENSTORE_UP);
281
282 xpvd_dip = devi;
259 ddi_report_dev(devi);
260
261 return (DDI_SUCCESS);
262}
263
264/*ARGSUSED*/
265static int
266xpvd_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)

--- 285 unchanged lines hidden (view full) ---

552 break;
553
554 case DDI_INTROP_BLOCKENABLE:
555 case DDI_INTROP_BLOCKDISABLE:
556 return (DDI_FAILURE);
557
558 case DDI_INTROP_SETMASK:
559 case DDI_INTROP_CLRMASK:
283 ddi_report_dev(devi);
284
285 return (DDI_SUCCESS);
286}
287
288/*ARGSUSED*/
289static int
290xpvd_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)

--- 285 unchanged lines hidden (view full) ---

576 break;
577
578 case DDI_INTROP_BLOCKENABLE:
579 case DDI_INTROP_BLOCKDISABLE:
580 return (DDI_FAILURE);
581
582 case DDI_INTROP_SETMASK:
583 case DDI_INTROP_CLRMASK:
584#ifdef XPV_HVM_DRIVER
585 return (DDI_ENOTSUP);
586#else
560 /*
561 * Handle this here
562 */
563 if (hdlp->ih_type != DDI_INTR_TYPE_FIXED)
564 return (DDI_FAILURE);
565 if (intr_op == DDI_INTROP_SETMASK) {
566 ec_disable_irq(hdlp->ih_vector);
567 } else {
568 ec_enable_irq(hdlp->ih_vector);
569 }
570 break;
587 /*
588 * Handle this here
589 */
590 if (hdlp->ih_type != DDI_INTR_TYPE_FIXED)
591 return (DDI_FAILURE);
592 if (intr_op == DDI_INTROP_SETMASK) {
593 ec_disable_irq(hdlp->ih_vector);
594 } else {
595 ec_enable_irq(hdlp->ih_vector);
596 }
597 break;
571
598#endif
572 case DDI_INTROP_GETPENDING:
599 case DDI_INTROP_GETPENDING:
600#ifdef XPV_HVM_DRIVER
601 return (DDI_ENOTSUP);
602#else
573 if (hdlp->ih_type != DDI_INTR_TYPE_FIXED)
574 return (DDI_FAILURE);
575 *(int *)result = ec_pending_irq(hdlp->ih_vector);
576 DDI_INTR_NEXDBG((CE_CONT, "xpvd: GETPENDING returned = %x\n",
577 *(int *)result));
578 break;
603 if (hdlp->ih_type != DDI_INTR_TYPE_FIXED)
604 return (DDI_FAILURE);
605 *(int *)result = ec_pending_irq(hdlp->ih_vector);
606 DDI_INTR_NEXDBG((CE_CONT, "xpvd: GETPENDING returned = %x\n",
607 *(int *)result));
608 break;
609#endif
579
580 case DDI_INTROP_NAVAIL:
581 *(int *)result = 1;
582 DDI_INTR_NEXDBG((CE_CONT, "xpvd: NAVAIL returned = %x\n",
583 *(int *)result));
584 break;
585
586 default:

--- 97 unchanged lines hidden (view full) ---

684 * Assign the address portion of the node name
685 */
686static int
687xpvd_name_child(dev_info_t *child, char *name, int namelen)
688{
689 int *domain, *vdev;
690 uint_t ndomain, nvdev;
691 char *unit_address;
610
611 case DDI_INTROP_NAVAIL:
612 *(int *)result = 1;
613 DDI_INTR_NEXDBG((CE_CONT, "xpvd: NAVAIL returned = %x\n",
614 *(int *)result));
615 break;
616
617 default:

--- 97 unchanged lines hidden (view full) ---

715 * Assign the address portion of the node name
716 */
717static int
718xpvd_name_child(dev_info_t *child, char *name, int namelen)
719{
720 int *domain, *vdev;
721 uint_t ndomain, nvdev;
722 char *unit_address;
723 int devno;
724#ifdef XPV_HVM_DRIVER
725 char *xip;
726 int xenstore_id;
727#endif
692
693 /*
694 * i_xpvd_parse_devname() knows the formats used by this
695 * routine. If this code changes, so must that.
696 */
697
698 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
699 "domain", &domain, &ndomain) != DDI_PROP_SUCCESS)

--- 16 unchanged lines hidden (view full) ---

716 ddi_prop_free(vdev);
717 ddi_prop_free(domain);
718 return (DDI_SUCCESS);
719 }
720 ddi_prop_free(domain);
721
722 /*
723 * Use "unit-address" property (frontend/softdev drivers).
728
729 /*
730 * i_xpvd_parse_devname() knows the formats used by this
731 * routine. If this code changes, so must that.
732 */
733
734 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, child, DDI_PROP_DONTPASS,
735 "domain", &domain, &ndomain) != DDI_PROP_SUCCESS)

--- 16 unchanged lines hidden (view full) ---

752 ddi_prop_free(vdev);
753 ddi_prop_free(domain);
754 return (DDI_SUCCESS);
755 }
756 ddi_prop_free(domain);
757
758 /*
759 * Use "unit-address" property (frontend/softdev drivers).
760 *
761 * For PV domains, the disk name should be a simple number. In an
762 * HVM domain, it will be a string of the form hdX. In the latter
763 * case we convert hda to 0, hdb to 1, and so on.
724 */
725 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
726 DDI_PROP_DONTPASS, "unit-address", &unit_address)
727 == DDI_PROP_SUCCESS) {
764 */
765 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
766 DDI_PROP_DONTPASS, "unit-address", &unit_address)
767 == DDI_PROP_SUCCESS) {
728 (void) snprintf(name, namelen, "%s", unit_address);
768 devno = -1;
769 if (unit_address[0] >= '0' && unit_address[0] <= '9')
770 (void) sscanf(unit_address, "%d", &devno);
771#ifdef XPV_HVM_DRIVER
772 /*
773 * XXX: we should really check the device class here. We
774 * always want to set hvm_vdev_num[] - even if we somehow
775 * end up with a non-hdX device name.
776 */
777 else if (strlen(unit_address) == 3 &&
778 unit_address[0] == 'h' && unit_address[1] == 'd') {
779 devno = unit_address[2] - 'a';
780 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, child,
781 DDI_PROP_DONTPASS, "xenstore-id", &xip)
782 == DDI_PROP_SUCCESS) {
783 (void) sscanf(xip, "%d", &xenstore_id);
784 ddi_prop_free(xip);
785 hvm_vdev_num[devno] = xenstore_id;
786 } else {
787 devno = -1;
788 }
789 }
790#endif
791
792 if (devno < 0) {
793 cmn_err(CE_WARN, "Unrecognized device: %s",
794 unit_address);
795 ddi_prop_free(unit_address);
796 return (DDI_FAILURE);
797 }
798 (void) snprintf(name, namelen, "%x", devno);
729 ddi_prop_free(unit_address);
730 return (DDI_SUCCESS);
731 }
732
733 return (DDI_FAILURE);
734}
735
736static int

--- 104 unchanged lines hidden (view full) ---

841 if (sscanf(caddr, "%d,%d", domp, vdevp) == 2) {
842 ret = B_TRUE;
843 goto done;
844 }
845
846 /* Frontend format is "<vdev>". */
847 *domp = DOMID_SELF;
848 if (sscanf(caddr, "%x", vdevp) == 1) {
799 ddi_prop_free(unit_address);
800 return (DDI_SUCCESS);
801 }
802
803 return (DDI_FAILURE);
804}
805
806static int

--- 104 unchanged lines hidden (view full) ---

911 if (sscanf(caddr, "%d,%d", domp, vdevp) == 2) {
912 ret = B_TRUE;
913 goto done;
914 }
915
916 /* Frontend format is "<vdev>". */
917 *domp = DOMID_SELF;
918 if (sscanf(caddr, "%x", vdevp) == 1) {
919#ifdef XPV_HVM_DRIVER
920 if (*devclassp == XEN_VBLK) {
921 if (*vdevp < 0 || *vdevp > 26) {
922 *vdevp = -1;
923 goto done;
924 }
925 *vdevp = hvm_vdev_num[*vdevp];
926 }
927#endif
849 ret = B_TRUE;
850 goto done;
851 }
852
928 ret = B_TRUE;
929 goto done;
930 }
931
932
853done:
854 kmem_free(device_name, len);
855 return (ret);
856}
857
858/*
859 * xpvd_bus_config()
860 *

--- 111 unchanged lines hidden ---
933done:
934 kmem_free(device_name, len);
935 return (ret);
936}
937
938/*
939 * xpvd_bus_config()
940 *

--- 111 unchanged lines hidden ---