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 --- |