Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-linus-4.10-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip

Pull xen fix from Juergen Gross:
"A fix for Xen running in nested virtualization environment"

* tag 'for-linus-4.10-rc4-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
partially revert "xen: Remove event channel notification through Xen PCI platform device"

+71
+71
drivers/xen/platform-pci.c
··· 42 42 static unsigned long platform_mmio; 43 43 static unsigned long platform_mmio_alloc; 44 44 static unsigned long platform_mmiolen; 45 + static uint64_t callback_via; 45 46 46 47 static unsigned long alloc_xen_mmio(unsigned long len) 47 48 { ··· 53 52 BUG_ON(platform_mmio_alloc > platform_mmiolen); 54 53 55 54 return addr; 55 + } 56 + 57 + static uint64_t get_callback_via(struct pci_dev *pdev) 58 + { 59 + u8 pin; 60 + int irq; 61 + 62 + irq = pdev->irq; 63 + if (irq < 16) 64 + return irq; /* ISA IRQ */ 65 + 66 + pin = pdev->pin; 67 + 68 + /* We don't know the GSI. Specify the PCI INTx line instead. */ 69 + return ((uint64_t)0x01 << HVM_CALLBACK_VIA_TYPE_SHIFT) | /* PCI INTx identifier */ 70 + ((uint64_t)pci_domain_nr(pdev->bus) << 32) | 71 + ((uint64_t)pdev->bus->number << 16) | 72 + ((uint64_t)(pdev->devfn & 0xff) << 8) | 73 + ((uint64_t)(pin - 1) & 3); 74 + } 75 + 76 + static irqreturn_t do_hvm_evtchn_intr(int irq, void *dev_id) 77 + { 78 + xen_hvm_evtchn_do_upcall(); 79 + return IRQ_HANDLED; 80 + } 81 + 82 + static int xen_allocate_irq(struct pci_dev *pdev) 83 + { 84 + return request_irq(pdev->irq, do_hvm_evtchn_intr, 85 + IRQF_NOBALANCING | IRQF_TRIGGER_RISING, 86 + "xen-platform-pci", pdev); 87 + } 88 + 89 + static int platform_pci_resume(struct pci_dev *pdev) 90 + { 91 + int err; 92 + if (!xen_pv_domain()) 93 + return 0; 94 + err = xen_set_callback_via(callback_via); 95 + if (err) { 96 + dev_err(&pdev->dev, "platform_pci_resume failure!\n"); 97 + return err; 98 + } 99 + return 0; 56 100 } 57 101 58 102 static int platform_pci_probe(struct pci_dev *pdev, ··· 138 92 platform_mmio = mmio_addr; 139 93 platform_mmiolen = mmio_len; 140 94 95 + /* 96 + * Xen HVM guests always use the vector callback mechanism. 97 + * L1 Dom0 in a nested Xen environment is a PV guest inside in an 98 + * HVM environment. It needs the platform-pci driver to get 99 + * notifications from L0 Xen, but it cannot use the vector callback 100 + * as it is not exported by L1 Xen. 101 + */ 102 + if (xen_pv_domain()) { 103 + ret = xen_allocate_irq(pdev); 104 + if (ret) { 105 + dev_warn(&pdev->dev, "request_irq failed err=%d\n", ret); 106 + goto out; 107 + } 108 + callback_via = get_callback_via(pdev); 109 + ret = xen_set_callback_via(callback_via); 110 + if (ret) { 111 + dev_warn(&pdev->dev, "Unable to set the evtchn callback " 112 + "err=%d\n", ret); 113 + goto out; 114 + } 115 + } 116 + 141 117 max_nr_gframes = gnttab_max_grant_frames(); 142 118 grant_frames = alloc_xen_mmio(PAGE_SIZE * max_nr_gframes); 143 119 ret = gnttab_setup_auto_xlat_frames(grant_frames); ··· 191 123 .name = DRV_NAME, 192 124 .probe = platform_pci_probe, 193 125 .id_table = platform_pci_tbl, 126 + #ifdef CONFIG_PM 127 + .resume_early = platform_pci_resume, 128 + #endif 194 129 }; 195 130 196 131 builtin_pci_driver(platform_driver);