Print this page
3605 Xen HVM hangs during boot if apix is enabled


  97 static void apix_post_cyclic_setup(void *);
  98 static int apix_post_cpu_start();
  99 static int apix_intr_ops(dev_info_t *, ddi_intr_handle_impl_t *,
 100     psm_intr_op_t, int *);
 101 
 102 /*
 103  * Helper functions for apix_intr_ops()
 104  */
 105 static void apix_redistribute_compute(void);
 106 static int apix_get_pending(apix_vector_t *);
 107 static apix_vector_t *apix_get_req_vector(ddi_intr_handle_impl_t *, ushort_t);
 108 static int apix_get_intr_info(ddi_intr_handle_impl_t *, apic_get_intr_t *);
 109 static char *apix_get_apic_type(void);
 110 static int apix_intx_get_pending(int);
 111 static void apix_intx_set_mask(int irqno);
 112 static void apix_intx_clear_mask(int irqno);
 113 static int apix_intx_get_shared(int irqno);
 114 static void apix_intx_set_shared(int irqno, int delta);
 115 static apix_vector_t *apix_intx_xlate_vector(dev_info_t *, int,
 116     struct intrspec *);
 117 static int apix_intx_alloc_vector(dev_info_t *, int, struct intrspec *);

 118 
 119 extern int apic_clkinit(int);
 120 
 121 /* IRM initialization for APIX PSM module */
 122 extern void apix_irm_init(void);
 123 
 124 extern int irm_enable;
 125 
 126 /*
 127  *      Local static data
 128  */
 129 static struct   psm_ops apix_ops = {
 130         apix_probe,
 131 
 132         apix_init,
 133         apix_picinit,
 134         apix_intr_enter,
 135         apix_intr_exit,
 136         apix_setspl,
 137         apix_addspl,


 244 int
 245 _fini(void)
 246 {
 247         return (psm_mod_fini(&apix_hdlp, &apix_psm_info));
 248 }
 249 
 250 int
 251 _info(struct modinfo *modinfop)
 252 {
 253         return (psm_mod_info(&apix_hdlp, &apix_psm_info, modinfop));
 254 }
 255 
 256 static int
 257 apix_probe()
 258 {
 259         int rval;
 260 
 261         if (apix_enable == 0)
 262                 return (PSM_FAILURE);
 263 
 264         /*
 265          * FIXME Temporarily disable apix module on Xen HVM platform due to
 266          * known hang during boot (see #3605).
 267          *
 268          * Please remove when/if the issue is resolved.
 269          */
 270         if (get_hwenv() == HW_XEN_HVM)
 271                 return (PSM_FAILURE);
 272 
 273         /* check for hw features if specified  */
 274         if (apix_hw_chk_enable) {
 275                 /* check if x2APIC mode is supported */
 276                 if ((apix_supported_hw & APIX_SUPPORT_X2APIC) ==
 277                     APIX_SUPPORT_X2APIC) {
 278                         if (apic_local_mode() == LOCAL_X2APIC) {
 279                                 /* x2APIC mode activated by BIOS, switch ops */
 280                                 apic_mode = LOCAL_X2APIC;
 281                                 apic_change_ops();
 282                         } else if (!apic_detect_x2apic()) {
 283                                 /* x2APIC mode is not supported in the hw */
 284                                 apix_enable = 0;
 285                         }
 286                 }
 287                 if (apix_enable == 0)
 288                         return (PSM_FAILURE);
 289         }
 290 
 291         rval = apic_probe_common(apix_psm_info.p_mach_idstring);
 292         if (rval == PSM_SUCCESS)


1167         case PSM_INTR_OP_ALLOC_VECTORS:
1168                 switch (hdlp->ih_type) {
1169                 case DDI_INTR_TYPE_MSI:
1170                         /* allocate MSI vectors */
1171                         *result = apix_alloc_msi(dip, hdlp->ih_inum,
1172                             hdlp->ih_scratch1,
1173                             (int)(uintptr_t)hdlp->ih_scratch2);
1174                         break;
1175                 case DDI_INTR_TYPE_MSIX:
1176                         /* allocate MSI-X vectors */
1177                         *result = apix_alloc_msix(dip, hdlp->ih_inum,
1178                             hdlp->ih_scratch1,
1179                             (int)(uintptr_t)hdlp->ih_scratch2);
1180                         break;
1181                 case DDI_INTR_TYPE_FIXED:
1182                         /* allocate or share vector for fixed */
1183                         if ((ihdl_plat_t *)hdlp->ih_private == NULL) {
1184                                 return (PSM_FAILURE);
1185                         }
1186                         ispec = ((ihdl_plat_t *)hdlp->ih_private)->ip_ispecp;
1187                         *result = apix_intx_alloc_vector(dip, hdlp->ih_inum,
1188                             ispec);
1189                         break;
1190                 default:
1191                         return (PSM_FAILURE);
1192                 }
1193                 break;
1194         case PSM_INTR_OP_FREE_VECTORS:
1195                 apix_free_vectors(dip, hdlp->ih_inum, hdlp->ih_scratch1,
1196                     hdlp->ih_type);
1197                 break;
1198         case PSM_INTR_OP_XLATE_VECTOR:
1199                 /*
1200                  * Vectors are allocated by ALLOC and freed by FREE.
1201                  * XLATE finds and returns APIX_VIRTVEC_VECTOR(cpu, vector).
1202                  */
1203                 *result = APIX_INVALID_VECT;
1204                 vecp = apix_get_dev_map(dip, hdlp->ih_inum, hdlp->ih_type);
1205                 if (vecp != NULL) {
1206                         *result = APIX_VIRTVECTOR(vecp->v_cpuid,
1207                             vecp->v_vector);
1208                         break;


2506                 bustype = BUS_EISA;
2507 
2508 nonpci:
2509         newirq = apix_intx_setup_nonpci(dip, inum, bustype, ispec);
2510         if (newirq != -1)
2511                 goto done;
2512 
2513 defconf:
2514         newirq = apix_intx_setup(dip, inum, irqno, NULL, ispec, NULL);
2515         if (newirq == -1) {
2516                 mutex_exit(&airq_mutex);
2517                 return (-1);
2518         }
2519 done:
2520         ASSERT(apic_irq_table[newirq]);
2521         mutex_exit(&airq_mutex);
2522         return (newirq);
2523 }
2524 
2525 static int
2526 apix_intx_alloc_vector(dev_info_t *dip, int inum, struct intrspec *ispec)

2527 {
2528         int irqno;
2529         apix_vector_t *vecp;
2530 
2531         if ((irqno = apix_intx_xlate_irq(dip, inum, ispec)) == -1)
2532                 return (0);
2533 
2534         if ((vecp = apix_alloc_intx(dip, inum, irqno)) == NULL)
2535                 return (0);
2536 


2537         DDI_INTR_IMPLDBG((CE_CONT, "apix_intx_alloc_vector: dip=0x%p name=%s "
2538             "irqno=0x%x cpuid=%d vector=0x%x\n",
2539             (void *)dip, ddi_driver_name(dip), irqno,
2540             vecp->v_cpuid, vecp->v_vector));
2541 
2542         return (1);
2543 }
2544 
2545 /*
2546  * Return the vector number if the translated IRQ for this device
2547  * has a vector mapping setup. If no IRQ setup exists or no vector is
2548  * allocated to it then return 0.
2549  */
2550 static apix_vector_t *
2551 apix_intx_xlate_vector(dev_info_t *dip, int inum, struct intrspec *ispec)
2552 {
2553         int irqno;
2554         apix_vector_t *vecp;
2555 
2556         /* get the IRQ number */




  97 static void apix_post_cyclic_setup(void *);
  98 static int apix_post_cpu_start();
  99 static int apix_intr_ops(dev_info_t *, ddi_intr_handle_impl_t *,
 100     psm_intr_op_t, int *);
 101 
 102 /*
 103  * Helper functions for apix_intr_ops()
 104  */
 105 static void apix_redistribute_compute(void);
 106 static int apix_get_pending(apix_vector_t *);
 107 static apix_vector_t *apix_get_req_vector(ddi_intr_handle_impl_t *, ushort_t);
 108 static int apix_get_intr_info(ddi_intr_handle_impl_t *, apic_get_intr_t *);
 109 static char *apix_get_apic_type(void);
 110 static int apix_intx_get_pending(int);
 111 static void apix_intx_set_mask(int irqno);
 112 static void apix_intx_clear_mask(int irqno);
 113 static int apix_intx_get_shared(int irqno);
 114 static void apix_intx_set_shared(int irqno, int delta);
 115 static apix_vector_t *apix_intx_xlate_vector(dev_info_t *, int,
 116     struct intrspec *);
 117 static int apix_intx_alloc_vector(dev_info_t *, ddi_intr_handle_impl_t *,
 118     struct intrspec *);
 119 
 120 extern int apic_clkinit(int);
 121 
 122 /* IRM initialization for APIX PSM module */
 123 extern void apix_irm_init(void);
 124 
 125 extern int irm_enable;
 126 
 127 /*
 128  *      Local static data
 129  */
 130 static struct   psm_ops apix_ops = {
 131         apix_probe,
 132 
 133         apix_init,
 134         apix_picinit,
 135         apix_intr_enter,
 136         apix_intr_exit,
 137         apix_setspl,
 138         apix_addspl,


 245 int
 246 _fini(void)
 247 {
 248         return (psm_mod_fini(&apix_hdlp, &apix_psm_info));
 249 }
 250 
 251 int
 252 _info(struct modinfo *modinfop)
 253 {
 254         return (psm_mod_info(&apix_hdlp, &apix_psm_info, modinfop));
 255 }
 256 
 257 static int
 258 apix_probe()
 259 {
 260         int rval;
 261 
 262         if (apix_enable == 0)
 263                 return (PSM_FAILURE);
 264 









 265         /* check for hw features if specified  */
 266         if (apix_hw_chk_enable) {
 267                 /* check if x2APIC mode is supported */
 268                 if ((apix_supported_hw & APIX_SUPPORT_X2APIC) ==
 269                     APIX_SUPPORT_X2APIC) {
 270                         if (apic_local_mode() == LOCAL_X2APIC) {
 271                                 /* x2APIC mode activated by BIOS, switch ops */
 272                                 apic_mode = LOCAL_X2APIC;
 273                                 apic_change_ops();
 274                         } else if (!apic_detect_x2apic()) {
 275                                 /* x2APIC mode is not supported in the hw */
 276                                 apix_enable = 0;
 277                         }
 278                 }
 279                 if (apix_enable == 0)
 280                         return (PSM_FAILURE);
 281         }
 282 
 283         rval = apic_probe_common(apix_psm_info.p_mach_idstring);
 284         if (rval == PSM_SUCCESS)


1159         case PSM_INTR_OP_ALLOC_VECTORS:
1160                 switch (hdlp->ih_type) {
1161                 case DDI_INTR_TYPE_MSI:
1162                         /* allocate MSI vectors */
1163                         *result = apix_alloc_msi(dip, hdlp->ih_inum,
1164                             hdlp->ih_scratch1,
1165                             (int)(uintptr_t)hdlp->ih_scratch2);
1166                         break;
1167                 case DDI_INTR_TYPE_MSIX:
1168                         /* allocate MSI-X vectors */
1169                         *result = apix_alloc_msix(dip, hdlp->ih_inum,
1170                             hdlp->ih_scratch1,
1171                             (int)(uintptr_t)hdlp->ih_scratch2);
1172                         break;
1173                 case DDI_INTR_TYPE_FIXED:
1174                         /* allocate or share vector for fixed */
1175                         if ((ihdl_plat_t *)hdlp->ih_private == NULL) {
1176                                 return (PSM_FAILURE);
1177                         }
1178                         ispec = ((ihdl_plat_t *)hdlp->ih_private)->ip_ispecp;
1179                         *result = apix_intx_alloc_vector(dip, hdlp, ispec);

1180                         break;
1181                 default:
1182                         return (PSM_FAILURE);
1183                 }
1184                 break;
1185         case PSM_INTR_OP_FREE_VECTORS:
1186                 apix_free_vectors(dip, hdlp->ih_inum, hdlp->ih_scratch1,
1187                     hdlp->ih_type);
1188                 break;
1189         case PSM_INTR_OP_XLATE_VECTOR:
1190                 /*
1191                  * Vectors are allocated by ALLOC and freed by FREE.
1192                  * XLATE finds and returns APIX_VIRTVEC_VECTOR(cpu, vector).
1193                  */
1194                 *result = APIX_INVALID_VECT;
1195                 vecp = apix_get_dev_map(dip, hdlp->ih_inum, hdlp->ih_type);
1196                 if (vecp != NULL) {
1197                         *result = APIX_VIRTVECTOR(vecp->v_cpuid,
1198                             vecp->v_vector);
1199                         break;


2497                 bustype = BUS_EISA;
2498 
2499 nonpci:
2500         newirq = apix_intx_setup_nonpci(dip, inum, bustype, ispec);
2501         if (newirq != -1)
2502                 goto done;
2503 
2504 defconf:
2505         newirq = apix_intx_setup(dip, inum, irqno, NULL, ispec, NULL);
2506         if (newirq == -1) {
2507                 mutex_exit(&airq_mutex);
2508                 return (-1);
2509         }
2510 done:
2511         ASSERT(apic_irq_table[newirq]);
2512         mutex_exit(&airq_mutex);
2513         return (newirq);
2514 }
2515 
2516 static int
2517 apix_intx_alloc_vector(dev_info_t *dip, ddi_intr_handle_impl_t *hdlp,
2518     struct intrspec *ispec)
2519 {
2520         int irqno;
2521         apix_vector_t *vecp;
2522 
2523         if ((irqno = apix_intx_xlate_irq(dip, hdlp->ih_inum, ispec)) == -1)
2524                 return (0);
2525 
2526         if ((vecp = apix_alloc_intx(dip, hdlp->ih_inum, irqno)) == NULL)
2527                 return (0);
2528 
2529         hdlp->ih_irq = irqno;
2530 
2531         DDI_INTR_IMPLDBG((CE_CONT, "apix_intx_alloc_vector: dip=0x%p name=%s "
2532             "irqno=0x%x cpuid=%d vector=0x%x\n",
2533             (void *)dip, ddi_driver_name(dip), irqno,
2534             vecp->v_cpuid, vecp->v_vector));
2535 
2536         return (1);
2537 }
2538 
2539 /*
2540  * Return the vector number if the translated IRQ for this device
2541  * has a vector mapping setup. If no IRQ setup exists or no vector is
2542  * allocated to it then return 0.
2543  */
2544 static apix_vector_t *
2545 apix_intx_xlate_vector(dev_info_t *dip, int inum, struct intrspec *ispec)
2546 {
2547         int irqno;
2548         apix_vector_t *vecp;
2549 
2550         /* get the IRQ number */