Merge branch '2.6.37-rc4-pvhvm-fixes' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm

* '2.6.37-rc4-pvhvm-fixes' of git://xenbits.xen.org/people/sstabellini/linux-pvhvm:
xen: unplug the emulated devices at resume time
xen: fix save/restore for PV on HVM guests with pirq remapping
xen: resume the pv console for hvm guests too
xen: fix MSI setup and teardown for PV on HVM guests
xen: use PHYSDEVOP_get_free_pirq to implement find_unbound_pirq

+114 -41
+20 -7
arch/x86/pci/xen.c
··· 70 struct xen_pci_frontend_ops *xen_pci_frontend; 71 EXPORT_SYMBOL_GPL(xen_pci_frontend); 72 73 static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq, 74 struct msi_msg *msg) 75 { ··· 86 MSI_ADDR_REDIRECTION_CPU | 87 MSI_ADDR_DEST_ID(pirq); 88 89 - msg->data = 90 - MSI_DATA_TRIGGER_EDGE | 91 - MSI_DATA_LEVEL_ASSERT | 92 - /* delivery mode reserved */ 93 - (3 << 8) | 94 - MSI_DATA_VECTOR(0); 95 } 96 97 static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) ··· 96 struct msi_msg msg; 97 98 list_for_each_entry(msidesc, &dev->msi_list, list) { 99 xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? 100 - "msi-x" : "msi", &irq, &pirq); 101 if (irq < 0 || pirq < 0) 102 goto error; 103 printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq);
··· 70 struct xen_pci_frontend_ops *xen_pci_frontend; 71 EXPORT_SYMBOL_GPL(xen_pci_frontend); 72 73 + #define XEN_PIRQ_MSI_DATA (MSI_DATA_TRIGGER_EDGE | \ 74 + MSI_DATA_LEVEL_ASSERT | (3 << 8) | MSI_DATA_VECTOR(0)) 75 + 76 static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq, 77 struct msi_msg *msg) 78 { ··· 83 MSI_ADDR_REDIRECTION_CPU | 84 MSI_ADDR_DEST_ID(pirq); 85 86 + msg->data = XEN_PIRQ_MSI_DATA; 87 } 88 89 static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) ··· 98 struct msi_msg msg; 99 100 list_for_each_entry(msidesc, &dev->msi_list, list) { 101 + __read_msi_msg(msidesc, &msg); 102 + pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) | 103 + ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff); 104 + if (xen_irq_from_pirq(pirq) >= 0 && msg.data == XEN_PIRQ_MSI_DATA) { 105 + xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? 106 + "msi-x" : "msi", &irq, &pirq, XEN_ALLOC_IRQ); 107 + if (irq < 0) 108 + goto error; 109 + ret = set_irq_msi(irq, msidesc); 110 + if (ret < 0) 111 + goto error_while; 112 + printk(KERN_DEBUG "xen: msi already setup: msi --> irq=%d" 113 + " pirq=%d\n", irq, pirq); 114 + return 0; 115 + } 116 xen_allocate_pirq_msi((type == PCI_CAP_ID_MSIX) ? 117 + "msi-x" : "msi", &irq, &pirq, (XEN_ALLOC_IRQ | XEN_ALLOC_PIRQ)); 118 if (irq < 0 || pirq < 0) 119 goto error; 120 printk(KERN_DEBUG "xen: msi --> irq=%d, pirq=%d\n", irq, pirq);
+1 -1
arch/x86/xen/platform-pci-unplug.c
··· 68 return 0; 69 } 70 71 - void __init xen_unplug_emulated_devices(void) 72 { 73 int r; 74
··· 68 return 0; 69 } 70 71 + void xen_unplug_emulated_devices(void) 72 { 73 int r; 74
+1
arch/x86/xen/suspend.c
··· 31 int cpu; 32 xen_hvm_init_shared_info(); 33 xen_callback_vector(); 34 if (xen_feature(XENFEAT_hvm_safe_pvclock)) { 35 for_each_online_cpu(cpu) { 36 xen_setup_runstate_info(cpu);
··· 31 int cpu; 32 xen_hvm_init_shared_info(); 33 xen_callback_vector(); 34 + xen_unplug_emulated_devices(); 35 if (xen_feature(XENFEAT_hvm_safe_pvclock)) { 36 for_each_online_cpu(cpu) { 37 xen_setup_runstate_info(cpu);
+1 -1
arch/x86/xen/xen-ops.h
··· 43 44 void xen_callback_vector(void); 45 void xen_hvm_init_shared_info(void); 46 - void __init xen_unplug_emulated_devices(void); 47 48 void __init xen_build_dynamic_phys_to_machine(void); 49
··· 43 44 void xen_callback_vector(void); 45 void xen_hvm_init_shared_info(void); 46 + void xen_unplug_emulated_devices(void); 47 48 void __init xen_build_dynamic_phys_to_machine(void); 49
+74 -31
drivers/xen/events.c
··· 105 106 static struct irq_info *irq_info; 107 static int *pirq_to_irq; 108 - static int nr_pirqs; 109 110 static int *evtchn_to_irq; 111 struct cpu_evtchn_s { ··· 384 return ret; 385 } 386 387 - /* callers of this function should make sure that PHYSDEVOP_get_nr_pirqs 388 - * succeeded otherwise nr_pirqs won't hold the right value */ 389 - static int find_unbound_pirq(void) 390 { 391 - int i; 392 - for (i = nr_pirqs-1; i >= 0; i--) { 393 if (pirq_to_irq[i] < 0) 394 return i; 395 } ··· 615 616 spin_lock(&irq_mapping_update_lock); 617 618 - if ((pirq > nr_pirqs) || (gsi > nr_irqs)) { 619 printk(KERN_WARNING "xen_map_pirq_gsi: %s %s is incorrect!\n", 620 - pirq > nr_pirqs ? "nr_pirqs" :"", 621 - gsi > nr_irqs ? "nr_irqs" : ""); 622 goto out; 623 } 624 ··· 668 #include <linux/msi.h> 669 #include "../pci/msi.h" 670 671 - void xen_allocate_pirq_msi(char *name, int *irq, int *pirq) 672 { 673 spin_lock(&irq_mapping_update_lock); 674 675 - *irq = find_unbound_irq(); 676 - if (*irq == -1) 677 - goto out; 678 679 - *pirq = find_unbound_pirq(); 680 - if (*pirq == -1) 681 - goto out; 682 683 set_irq_chip_and_handler_name(*irq, &xen_pirq_chip, 684 handle_level_irq, name); ··· 770 printk(KERN_WARNING "unmap irq failed %d\n", rc); 771 goto out; 772 } 773 } 774 irq_info[irq] = mk_unbound_info(); 775 ··· 789 int xen_gsi_from_irq(unsigned irq) 790 { 791 return gsi_from_irq(irq); 792 } 793 794 int bind_evtchn_to_irq(unsigned int evtchn) ··· 1293 return ret; 1294 } 1295 1296 static void restore_cpu_virqs(unsigned int cpu) 1297 { 1298 struct evtchn_bind_virq bind_virq; ··· 1472 1473 unmask_evtchn(evtchn); 1474 } 1475 } 1476 1477 static struct irq_chip xen_dynamic_chip __read_mostly = { ··· 1558 1559 void __init xen_init_IRQ(void) 1560 { 1561 - int i, rc; 1562 - struct physdev_nr_pirqs op_nr_pirqs; 1563 1564 cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s), 1565 GFP_KERNEL); 1566 irq_info = kcalloc(nr_irqs, sizeof(*irq_info), GFP_KERNEL); 1567 1568 - rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_nr_pirqs, &op_nr_pirqs); 1569 - if (rc < 0) { 1570 - nr_pirqs = nr_irqs; 1571 - if (rc != -ENOSYS) 1572 - printk(KERN_WARNING "PHYSDEVOP_get_nr_pirqs returned rc=%d\n", rc); 1573 - } else { 1574 - if (xen_pv_domain() && !xen_initial_domain()) 1575 - nr_pirqs = max((int)op_nr_pirqs.nr_pirqs, nr_irqs); 1576 - else 1577 - nr_pirqs = op_nr_pirqs.nr_pirqs; 1578 - } 1579 - pirq_to_irq = kcalloc(nr_pirqs, sizeof(*pirq_to_irq), GFP_KERNEL); 1580 - for (i = 0; i < nr_pirqs; i++) 1581 pirq_to_irq[i] = -1; 1582 1583 evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq),
··· 105 106 static struct irq_info *irq_info; 107 static int *pirq_to_irq; 108 109 static int *evtchn_to_irq; 110 struct cpu_evtchn_s { ··· 385 return ret; 386 } 387 388 + static int find_unbound_pirq(int type) 389 { 390 + int rc, i; 391 + struct physdev_get_free_pirq op_get_free_pirq; 392 + op_get_free_pirq.type = type; 393 + 394 + rc = HYPERVISOR_physdev_op(PHYSDEVOP_get_free_pirq, &op_get_free_pirq); 395 + if (!rc) 396 + return op_get_free_pirq.pirq; 397 + 398 + for (i = 0; i < nr_irqs; i++) { 399 if (pirq_to_irq[i] < 0) 400 return i; 401 } ··· 611 612 spin_lock(&irq_mapping_update_lock); 613 614 + if ((pirq > nr_irqs) || (gsi > nr_irqs)) { 615 printk(KERN_WARNING "xen_map_pirq_gsi: %s %s is incorrect!\n", 616 + pirq > nr_irqs ? "pirq" :"", 617 + gsi > nr_irqs ? "gsi" : ""); 618 goto out; 619 } 620 ··· 664 #include <linux/msi.h> 665 #include "../pci/msi.h" 666 667 + void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc) 668 { 669 spin_lock(&irq_mapping_update_lock); 670 671 + if (alloc & XEN_ALLOC_IRQ) { 672 + *irq = find_unbound_irq(); 673 + if (*irq == -1) 674 + goto out; 675 + } 676 677 + if (alloc & XEN_ALLOC_PIRQ) { 678 + *pirq = find_unbound_pirq(MAP_PIRQ_TYPE_MSI); 679 + if (*pirq == -1) 680 + goto out; 681 + } 682 683 set_irq_chip_and_handler_name(*irq, &xen_pirq_chip, 684 handle_level_irq, name); ··· 762 printk(KERN_WARNING "unmap irq failed %d\n", rc); 763 goto out; 764 } 765 + pirq_to_irq[info->u.pirq.pirq] = -1; 766 } 767 irq_info[irq] = mk_unbound_info(); 768 ··· 780 int xen_gsi_from_irq(unsigned irq) 781 { 782 return gsi_from_irq(irq); 783 + } 784 + 785 + int xen_irq_from_pirq(unsigned pirq) 786 + { 787 + return pirq_to_irq[pirq]; 788 } 789 790 int bind_evtchn_to_irq(unsigned int evtchn) ··· 1279 return ret; 1280 } 1281 1282 + static void restore_cpu_pirqs(void) 1283 + { 1284 + int pirq, rc, irq, gsi; 1285 + struct physdev_map_pirq map_irq; 1286 + 1287 + for (pirq = 0; pirq < nr_irqs; pirq++) { 1288 + irq = pirq_to_irq[pirq]; 1289 + if (irq == -1) 1290 + continue; 1291 + 1292 + /* save/restore of PT devices doesn't work, so at this point the 1293 + * only devices present are GSI based emulated devices */ 1294 + gsi = gsi_from_irq(irq); 1295 + if (!gsi) 1296 + continue; 1297 + 1298 + map_irq.domid = DOMID_SELF; 1299 + map_irq.type = MAP_PIRQ_TYPE_GSI; 1300 + map_irq.index = gsi; 1301 + map_irq.pirq = pirq; 1302 + 1303 + rc = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq); 1304 + if (rc) { 1305 + printk(KERN_WARNING "xen map irq failed gsi=%d irq=%d pirq=%d rc=%d\n", 1306 + gsi, irq, pirq, rc); 1307 + irq_info[irq] = mk_unbound_info(); 1308 + pirq_to_irq[pirq] = -1; 1309 + continue; 1310 + } 1311 + 1312 + printk(KERN_DEBUG "xen: --> irq=%d, pirq=%d\n", irq, map_irq.pirq); 1313 + 1314 + startup_pirq(irq); 1315 + } 1316 + } 1317 + 1318 static void restore_cpu_virqs(unsigned int cpu) 1319 { 1320 struct evtchn_bind_virq bind_virq; ··· 1422 1423 unmask_evtchn(evtchn); 1424 } 1425 + 1426 + restore_cpu_pirqs(); 1427 } 1428 1429 static struct irq_chip xen_dynamic_chip __read_mostly = { ··· 1506 1507 void __init xen_init_IRQ(void) 1508 { 1509 + int i; 1510 1511 cpu_evtchn_mask_p = kcalloc(nr_cpu_ids, sizeof(struct cpu_evtchn_s), 1512 GFP_KERNEL); 1513 irq_info = kcalloc(nr_irqs, sizeof(*irq_info), GFP_KERNEL); 1514 1515 + /* We are using nr_irqs as the maximum number of pirq available but 1516 + * that number is actually chosen by Xen and we don't know exactly 1517 + * what it is. Be careful choosing high pirq numbers. */ 1518 + pirq_to_irq = kcalloc(nr_irqs, sizeof(*pirq_to_irq), GFP_KERNEL); 1519 + for (i = 0; i < nr_irqs; i++) 1520 pirq_to_irq[i] = -1; 1521 1522 evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq),
+1
drivers/xen/manage.c
··· 49 50 if (!*cancelled) { 51 xen_irq_resume(); 52 xen_timer_resume(); 53 } 54
··· 49 50 if (!*cancelled) { 51 xen_irq_resume(); 52 + xen_console_resume(); 53 xen_timer_resume(); 54 } 55
+6 -1
include/xen/events.h
··· 76 77 #ifdef CONFIG_PCI_MSI 78 /* Allocate an irq and a pirq to be used with MSIs. */ 79 - void xen_allocate_pirq_msi(char *name, int *irq, int *pirq); 80 int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type); 81 #endif 82 ··· 90 91 /* Return gsi allocated to pirq */ 92 int xen_gsi_from_irq(unsigned pirq); 93 94 #endif /* _XEN_EVENTS_H */
··· 76 77 #ifdef CONFIG_PCI_MSI 78 /* Allocate an irq and a pirq to be used with MSIs. */ 79 + #define XEN_ALLOC_PIRQ (1 << 0) 80 + #define XEN_ALLOC_IRQ (1 << 1) 81 + void xen_allocate_pirq_msi(char *name, int *irq, int *pirq, int alloc_mask); 82 int xen_create_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int type); 83 #endif 84 ··· 88 89 /* Return gsi allocated to pirq */ 90 int xen_gsi_from_irq(unsigned pirq); 91 + 92 + /* Return irq from pirq */ 93 + int xen_irq_from_pirq(unsigned pirq); 94 95 #endif /* _XEN_EVENTS_H */
+10
include/xen/interface/physdev.h
··· 188 uint32_t nr_pirqs; 189 }; 190 191 /* 192 * Notify that some PIRQ-bound event channels have been unmasked. 193 * ** This command is obsolete since interface version 0x00030202 and is **
··· 188 uint32_t nr_pirqs; 189 }; 190 191 + /* type is MAP_PIRQ_TYPE_GSI or MAP_PIRQ_TYPE_MSI 192 + * the hypercall returns a free pirq */ 193 + #define PHYSDEVOP_get_free_pirq 23 194 + struct physdev_get_free_pirq { 195 + /* IN */ 196 + int type; 197 + /* OUT */ 198 + uint32_t pirq; 199 + }; 200 + 201 /* 202 * Notify that some PIRQ-bound event channels have been unmasked. 203 * ** This command is obsolete since interface version 0x00030202 and is **