aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/xen/swiotlb-xen.h2
-rw-r--r--arch/x86/xen/enlighten.c8
-rw-r--r--arch/x86/xen/pci-swiotlb-xen.c47
-rw-r--r--arch/x86/xen/vga.c7
-rw-r--r--drivers/net/xen-netback/netback.c11
-rw-r--r--drivers/pci/xen-pcifront.c13
-rw-r--r--drivers/xen/grant-table.c53
-rw-r--r--drivers/xen/swiotlb-xen.c101
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c136
-rw-r--r--drivers/xen/xenbus/xenbus_client.c6
-rw-r--r--include/linux/swiotlb.h1
-rw-r--r--include/xen/grant_table.h12
-rw-r--r--include/xen/interface/platform.h3
-rw-r--r--include/xen/interface/xen.h1
-rw-r--r--include/xen/swiotlb-xen.h2
-rw-r--r--lib/swiotlb.c33
16 files changed, 349 insertions, 87 deletions
diff --git a/arch/x86/include/asm/xen/swiotlb-xen.h b/arch/x86/include/asm/xen/swiotlb-xen.h
index 1be1ab7d6a41..ee52fcac6f72 100644
--- a/arch/x86/include/asm/xen/swiotlb-xen.h
+++ b/arch/x86/include/asm/xen/swiotlb-xen.h
@@ -5,10 +5,12 @@
5extern int xen_swiotlb; 5extern int xen_swiotlb;
6extern int __init pci_xen_swiotlb_detect(void); 6extern int __init pci_xen_swiotlb_detect(void);
7extern void __init pci_xen_swiotlb_init(void); 7extern void __init pci_xen_swiotlb_init(void);
8extern int pci_xen_swiotlb_init_late(void);
8#else 9#else
9#define xen_swiotlb (0) 10#define xen_swiotlb (0)
10static inline int __init pci_xen_swiotlb_detect(void) { return 0; } 11static inline int __init pci_xen_swiotlb_detect(void) { return 0; }
11static inline void __init pci_xen_swiotlb_init(void) { } 12static inline void __init pci_xen_swiotlb_init(void) { }
13static inline int pci_xen_swiotlb_init_late(void) { return -ENXIO; }
12#endif 14#endif
13 15
14#endif /* _ASM_X86_SWIOTLB_XEN_H */ 16#endif /* _ASM_X86_SWIOTLB_XEN_H */
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 689a4c9da866..70f140447a28 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1441,11 +1441,19 @@ asmlinkage void __init xen_start_kernel(void)
1441 const struct dom0_vga_console_info *info = 1441 const struct dom0_vga_console_info *info =
1442 (void *)((char *)xen_start_info + 1442 (void *)((char *)xen_start_info +
1443 xen_start_info->console.dom0.info_off); 1443 xen_start_info->console.dom0.info_off);
1444 struct xen_platform_op op = {
1445 .cmd = XENPF_firmware_info,
1446 .interface_version = XENPF_INTERFACE_VERSION,
1447 .u.firmware_info.type = XEN_FW_KBD_SHIFT_FLAGS,
1448 };
1444 1449
1445 xen_init_vga(info, xen_start_info->console.dom0.info_size); 1450 xen_init_vga(info, xen_start_info->console.dom0.info_size);
1446 xen_start_info->console.domU.mfn = 0; 1451 xen_start_info->console.domU.mfn = 0;
1447 xen_start_info->console.domU.evtchn = 0; 1452 xen_start_info->console.domU.evtchn = 0;
1448 1453
1454 if (HYPERVISOR_dom0_op(&op) == 0)
1455 boot_params.kbd_status = op.u.firmware_info.u.kbd_shift_flags;
1456
1449 xen_init_apic(); 1457 xen_init_apic();
1450 1458
1451 /* Make sure ACS will be enabled */ 1459 /* Make sure ACS will be enabled */
diff --git a/arch/x86/xen/pci-swiotlb-xen.c b/arch/x86/xen/pci-swiotlb-xen.c
index 1ab45941502d..969570491c39 100644
--- a/arch/x86/xen/pci-swiotlb-xen.c
+++ b/arch/x86/xen/pci-swiotlb-xen.c
@@ -8,7 +8,14 @@
8#include <xen/xen.h> 8#include <xen/xen.h>
9#include <asm/iommu_table.h> 9#include <asm/iommu_table.h>
10 10
11
11#include <asm/xen/swiotlb-xen.h> 12#include <asm/xen/swiotlb-xen.h>
13#ifdef CONFIG_X86_64
14#include <asm/iommu.h>
15#include <asm/dma.h>
16#endif
17#include <linux/export.h>
18
12int xen_swiotlb __read_mostly; 19int xen_swiotlb __read_mostly;
13 20
14static struct dma_map_ops xen_swiotlb_dma_ops = { 21static struct dma_map_ops xen_swiotlb_dma_ops = {
@@ -35,33 +42,63 @@ static struct dma_map_ops xen_swiotlb_dma_ops = {
35int __init pci_xen_swiotlb_detect(void) 42int __init pci_xen_swiotlb_detect(void)
36{ 43{
37 44
45 if (!xen_pv_domain())
46 return 0;
47
38 /* If running as PV guest, either iommu=soft, or swiotlb=force will 48 /* If running as PV guest, either iommu=soft, or swiotlb=force will
39 * activate this IOMMU. If running as PV privileged, activate it 49 * activate this IOMMU. If running as PV privileged, activate it
40 * irregardless. 50 * irregardless.
41 */ 51 */
42 if ((xen_initial_domain() || swiotlb || swiotlb_force) && 52 if ((xen_initial_domain() || swiotlb || swiotlb_force))
43 (xen_pv_domain()))
44 xen_swiotlb = 1; 53 xen_swiotlb = 1;
45 54
46 /* If we are running under Xen, we MUST disable the native SWIOTLB. 55 /* If we are running under Xen, we MUST disable the native SWIOTLB.
47 * Don't worry about swiotlb_force flag activating the native, as 56 * Don't worry about swiotlb_force flag activating the native, as
48 * the 'swiotlb' flag is the only one turning it on. */ 57 * the 'swiotlb' flag is the only one turning it on. */
49 if (xen_pv_domain()) 58 swiotlb = 0;
50 swiotlb = 0;
51 59
60#ifdef CONFIG_X86_64
61 /* pci_swiotlb_detect_4gb turns on native SWIOTLB if no_iommu == 0
62 * (so no iommu=X command line over-writes).
63 * Considering that PV guests do not want the *native SWIOTLB* but
64 * only Xen SWIOTLB it is not useful to us so set no_iommu=1 here.
65 */
66 if (max_pfn > MAX_DMA32_PFN)
67 no_iommu = 1;
68#endif
52 return xen_swiotlb; 69 return xen_swiotlb;
53} 70}
54 71
55void __init pci_xen_swiotlb_init(void) 72void __init pci_xen_swiotlb_init(void)
56{ 73{
57 if (xen_swiotlb) { 74 if (xen_swiotlb) {
58 xen_swiotlb_init(1); 75 xen_swiotlb_init(1, true /* early */);
59 dma_ops = &xen_swiotlb_dma_ops; 76 dma_ops = &xen_swiotlb_dma_ops;
60 77
61 /* Make sure ACS will be enabled */ 78 /* Make sure ACS will be enabled */
62 pci_request_acs(); 79 pci_request_acs();
63 } 80 }
64} 81}
82
83int pci_xen_swiotlb_init_late(void)
84{
85 int rc;
86
87 if (xen_swiotlb)
88 return 0;
89
90 rc = xen_swiotlb_init(1, false /* late */);
91 if (rc)
92 return rc;
93
94 dma_ops = &xen_swiotlb_dma_ops;
95 /* Make sure ACS will be enabled */
96 pci_request_acs();
97
98 return 0;
99}
100EXPORT_SYMBOL_GPL(pci_xen_swiotlb_init_late);
101
65IOMMU_INIT_FINISH(pci_xen_swiotlb_detect, 102IOMMU_INIT_FINISH(pci_xen_swiotlb_detect,
66 NULL, 103 NULL,
67 pci_xen_swiotlb_init, 104 pci_xen_swiotlb_init,
diff --git a/arch/x86/xen/vga.c b/arch/x86/xen/vga.c
index 1cd7f4d11e29..6722e3733f02 100644
--- a/arch/x86/xen/vga.c
+++ b/arch/x86/xen/vga.c
@@ -35,6 +35,7 @@ void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size)
35 info->u.text_mode_3.font_height; 35 info->u.text_mode_3.font_height;
36 break; 36 break;
37 37
38 case XEN_VGATYPE_EFI_LFB:
38 case XEN_VGATYPE_VESA_LFB: 39 case XEN_VGATYPE_VESA_LFB:
39 if (size < offsetof(struct dom0_vga_console_info, 40 if (size < offsetof(struct dom0_vga_console_info,
40 u.vesa_lfb.gbl_caps)) 41 u.vesa_lfb.gbl_caps))
@@ -54,6 +55,12 @@ void __init xen_init_vga(const struct dom0_vga_console_info *info, size_t size)
54 screen_info->blue_pos = info->u.vesa_lfb.blue_pos; 55 screen_info->blue_pos = info->u.vesa_lfb.blue_pos;
55 screen_info->rsvd_size = info->u.vesa_lfb.rsvd_size; 56 screen_info->rsvd_size = info->u.vesa_lfb.rsvd_size;
56 screen_info->rsvd_pos = info->u.vesa_lfb.rsvd_pos; 57 screen_info->rsvd_pos = info->u.vesa_lfb.rsvd_pos;
58
59 if (info->video_type == XEN_VGATYPE_EFI_LFB) {
60 screen_info->orig_video_isVGA = VIDEO_TYPE_EFI;
61 break;
62 }
63
57 if (size >= offsetof(struct dom0_vga_console_info, 64 if (size >= offsetof(struct dom0_vga_console_info,
58 u.vesa_lfb.gbl_caps) 65 u.vesa_lfb.gbl_caps)
59 + sizeof(info->u.vesa_lfb.gbl_caps)) 66 + sizeof(info->u.vesa_lfb.gbl_caps))
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 1c0a30240d97..4ebfcf3d8a3b 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -636,9 +636,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk)
636 return; 636 return;
637 637
638 BUG_ON(npo.copy_prod > ARRAY_SIZE(netbk->grant_copy_op)); 638 BUG_ON(npo.copy_prod > ARRAY_SIZE(netbk->grant_copy_op));
639 ret = HYPERVISOR_grant_table_op(GNTTABOP_copy, &netbk->grant_copy_op, 639 gnttab_batch_copy(netbk->grant_copy_op, npo.copy_prod);
640 npo.copy_prod);
641 BUG_ON(ret != 0);
642 640
643 while ((skb = __skb_dequeue(&rxq)) != NULL) { 641 while ((skb = __skb_dequeue(&rxq)) != NULL) {
644 sco = (struct skb_cb_overlay *)skb->cb; 642 sco = (struct skb_cb_overlay *)skb->cb;
@@ -1461,18 +1459,15 @@ static void xen_netbk_tx_submit(struct xen_netbk *netbk)
1461static void xen_netbk_tx_action(struct xen_netbk *netbk) 1459static void xen_netbk_tx_action(struct xen_netbk *netbk)
1462{ 1460{
1463 unsigned nr_gops; 1461 unsigned nr_gops;
1464 int ret;
1465 1462
1466 nr_gops = xen_netbk_tx_build_gops(netbk); 1463 nr_gops = xen_netbk_tx_build_gops(netbk);
1467 1464
1468 if (nr_gops == 0) 1465 if (nr_gops == 0)
1469 return; 1466 return;
1470 ret = HYPERVISOR_grant_table_op(GNTTABOP_copy,
1471 netbk->tx_copy_ops, nr_gops);
1472 BUG_ON(ret);
1473 1467
1474 xen_netbk_tx_submit(netbk); 1468 gnttab_batch_copy(netbk->tx_copy_ops, nr_gops);
1475 1469
1470 xen_netbk_tx_submit(netbk);
1476} 1471}
1477 1472
1478static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx) 1473static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx)
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index a4d901def8f2..7d6773535b67 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -21,6 +21,7 @@
21#include <linux/bitops.h> 21#include <linux/bitops.h>
22#include <linux/time.h> 22#include <linux/time.h>
23 23
24#include <asm/xen/swiotlb-xen.h>
24#define INVALID_GRANT_REF (0) 25#define INVALID_GRANT_REF (0)
25#define INVALID_EVTCHN (-1) 26#define INVALID_EVTCHN (-1)
26 27
@@ -668,7 +669,7 @@ static irqreturn_t pcifront_handler_aer(int irq, void *dev)
668 schedule_pcifront_aer_op(pdev); 669 schedule_pcifront_aer_op(pdev);
669 return IRQ_HANDLED; 670 return IRQ_HANDLED;
670} 671}
671static int pcifront_connect(struct pcifront_device *pdev) 672static int pcifront_connect_and_init_dma(struct pcifront_device *pdev)
672{ 673{
673 int err = 0; 674 int err = 0;
674 675
@@ -681,9 +682,13 @@ static int pcifront_connect(struct pcifront_device *pdev)
681 dev_err(&pdev->xdev->dev, "PCI frontend already installed!\n"); 682 dev_err(&pdev->xdev->dev, "PCI frontend already installed!\n");
682 err = -EEXIST; 683 err = -EEXIST;
683 } 684 }
684
685 spin_unlock(&pcifront_dev_lock); 685 spin_unlock(&pcifront_dev_lock);
686 686
687 if (!err && !swiotlb_nr_tbl()) {
688 err = pci_xen_swiotlb_init_late();
689 if (err)
690 dev_err(&pdev->xdev->dev, "Could not setup SWIOTLB!\n");
691 }
687 return err; 692 return err;
688} 693}
689 694
@@ -842,10 +847,10 @@ static int __devinit pcifront_try_connect(struct pcifront_device *pdev)
842 XenbusStateInitialised) 847 XenbusStateInitialised)
843 goto out; 848 goto out;
844 849
845 err = pcifront_connect(pdev); 850 err = pcifront_connect_and_init_dma(pdev);
846 if (err) { 851 if (err) {
847 xenbus_dev_fatal(pdev->xdev, err, 852 xenbus_dev_fatal(pdev->xdev, err,
848 "Error connecting PCI Frontend"); 853 "Error setting up PCI Frontend");
849 goto out; 854 goto out;
850 } 855 }
851 856
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index eea81cf8a2a5..3a567b15600b 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -38,6 +38,7 @@
38#include <linux/vmalloc.h> 38#include <linux/vmalloc.h>
39#include <linux/uaccess.h> 39#include <linux/uaccess.h>
40#include <linux/io.h> 40#include <linux/io.h>
41#include <linux/delay.h>
41#include <linux/hardirq.h> 42#include <linux/hardirq.h>
42 43
43#include <xen/xen.h> 44#include <xen/xen.h>
@@ -823,6 +824,52 @@ unsigned int gnttab_max_grant_frames(void)
823} 824}
824EXPORT_SYMBOL_GPL(gnttab_max_grant_frames); 825EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
825 826
827/* Handling of paged out grant targets (GNTST_eagain) */
828#define MAX_DELAY 256
829static inline void
830gnttab_retry_eagain_gop(unsigned int cmd, void *gop, int16_t *status,
831 const char *func)
832{
833 unsigned delay = 1;
834
835 do {
836 BUG_ON(HYPERVISOR_grant_table_op(cmd, gop, 1));
837 if (*status == GNTST_eagain)
838 msleep(delay++);
839 } while ((*status == GNTST_eagain) && (delay < MAX_DELAY));
840
841 if (delay >= MAX_DELAY) {
842 printk(KERN_ERR "%s: %s eagain grant\n", func, current->comm);
843 *status = GNTST_bad_page;
844 }
845}
846
847void gnttab_batch_map(struct gnttab_map_grant_ref *batch, unsigned count)
848{
849 struct gnttab_map_grant_ref *op;
850
851 if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, batch, count))
852 BUG();
853 for (op = batch; op < batch + count; op++)
854 if (op->status == GNTST_eagain)
855 gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, op,
856 &op->status, __func__);
857}
858EXPORT_SYMBOL_GPL(gnttab_batch_map);
859
860void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count)
861{
862 struct gnttab_copy *op;
863
864 if (HYPERVISOR_grant_table_op(GNTTABOP_copy, batch, count))
865 BUG();
866 for (op = batch; op < batch + count; op++)
867 if (op->status == GNTST_eagain)
868 gnttab_retry_eagain_gop(GNTTABOP_copy, op,
869 &op->status, __func__);
870}
871EXPORT_SYMBOL_GPL(gnttab_batch_copy);
872
826int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, 873int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
827 struct gnttab_map_grant_ref *kmap_ops, 874 struct gnttab_map_grant_ref *kmap_ops,
828 struct page **pages, unsigned int count) 875 struct page **pages, unsigned int count)
@@ -836,6 +883,12 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
836 if (ret) 883 if (ret)
837 return ret; 884 return ret;
838 885
886 /* Retry eagain maps */
887 for (i = 0; i < count; i++)
888 if (map_ops[i].status == GNTST_eagain)
889 gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, map_ops + i,
890 &map_ops[i].status, __func__);
891
839 if (xen_feature(XENFEAT_auto_translated_physmap)) 892 if (xen_feature(XENFEAT_auto_translated_physmap))
840 return ret; 893 return ret;
841 894
diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c
index 2e74dba6a04d..58db6df866ef 100644
--- a/drivers/xen/swiotlb-xen.c
+++ b/drivers/xen/swiotlb-xen.c
@@ -144,31 +144,72 @@ xen_swiotlb_fixup(void *buf, size_t size, unsigned long nslabs)
144 } while (i < nslabs); 144 } while (i < nslabs);
145 return 0; 145 return 0;
146} 146}
147static unsigned long xen_set_nslabs(unsigned long nr_tbl)
148{
149 if (!nr_tbl) {
150 xen_io_tlb_nslabs = (64 * 1024 * 1024 >> IO_TLB_SHIFT);
151 xen_io_tlb_nslabs = ALIGN(xen_io_tlb_nslabs, IO_TLB_SEGSIZE);
152 } else
153 xen_io_tlb_nslabs = nr_tbl;
154
155 return xen_io_tlb_nslabs << IO_TLB_SHIFT;
156}
157
158enum xen_swiotlb_err {
159 XEN_SWIOTLB_UNKNOWN = 0,
160 XEN_SWIOTLB_ENOMEM,
161 XEN_SWIOTLB_EFIXUP
162};
147 163
148void __init xen_swiotlb_init(int verbose) 164static const char *xen_swiotlb_error(enum xen_swiotlb_err err)
149{ 165{
150 unsigned long bytes; 166 switch (err) {
167 case XEN_SWIOTLB_ENOMEM:
168 return "Cannot allocate Xen-SWIOTLB buffer\n";
169 case XEN_SWIOTLB_EFIXUP:
170 return "Failed to get contiguous memory for DMA from Xen!\n"\
171 "You either: don't have the permissions, do not have"\
172 " enough free memory under 4GB, or the hypervisor memory"\
173 " is too fragmented!";
174 default:
175 break;
176 }
177 return "";
178}
179int __ref xen_swiotlb_init(int verbose, bool early)
180{
181 unsigned long bytes, order;
151 int rc = -ENOMEM; 182 int rc = -ENOMEM;
152 unsigned long nr_tbl; 183 enum xen_swiotlb_err m_ret = XEN_SWIOTLB_UNKNOWN;
153 char *m = NULL;
154 unsigned int repeat = 3; 184 unsigned int repeat = 3;
155 185
156 nr_tbl = swiotlb_nr_tbl(); 186 xen_io_tlb_nslabs = swiotlb_nr_tbl();
157 if (nr_tbl)
158 xen_io_tlb_nslabs = nr_tbl;
159 else {
160 xen_io_tlb_nslabs = (64 * 1024 * 1024 >> IO_TLB_SHIFT);
161 xen_io_tlb_nslabs = ALIGN(xen_io_tlb_nslabs, IO_TLB_SEGSIZE);
162 }
163retry: 187retry:
164 bytes = xen_io_tlb_nslabs << IO_TLB_SHIFT; 188 bytes = xen_set_nslabs(xen_io_tlb_nslabs);
165 189 order = get_order(xen_io_tlb_nslabs << IO_TLB_SHIFT);
166 /* 190 /*
167 * Get IO TLB memory from any location. 191 * Get IO TLB memory from any location.
168 */ 192 */
169 xen_io_tlb_start = alloc_bootmem_pages(PAGE_ALIGN(bytes)); 193 if (early)
194 xen_io_tlb_start = alloc_bootmem_pages(PAGE_ALIGN(bytes));
195 else {
196#define SLABS_PER_PAGE (1 << (PAGE_SHIFT - IO_TLB_SHIFT))
197#define IO_TLB_MIN_SLABS ((1<<20) >> IO_TLB_SHIFT)
198 while ((SLABS_PER_PAGE << order) > IO_TLB_MIN_SLABS) {
199 xen_io_tlb_start = (void *)__get_free_pages(__GFP_NOWARN, order);
200 if (xen_io_tlb_start)
201 break;
202 order--;
203 }
204 if (order != get_order(bytes)) {
205 pr_warn("Warning: only able to allocate %ld MB "
206 "for software IO TLB\n", (PAGE_SIZE << order) >> 20);
207 xen_io_tlb_nslabs = SLABS_PER_PAGE << order;
208 bytes = xen_io_tlb_nslabs << IO_TLB_SHIFT;
209 }
210 }
170 if (!xen_io_tlb_start) { 211 if (!xen_io_tlb_start) {
171 m = "Cannot allocate Xen-SWIOTLB buffer!\n"; 212 m_ret = XEN_SWIOTLB_ENOMEM;
172 goto error; 213 goto error;
173 } 214 }
174 xen_io_tlb_end = xen_io_tlb_start + bytes; 215 xen_io_tlb_end = xen_io_tlb_start + bytes;
@@ -179,17 +220,22 @@ retry:
179 bytes, 220 bytes,
180 xen_io_tlb_nslabs); 221 xen_io_tlb_nslabs);
181 if (rc) { 222 if (rc) {
182 free_bootmem(__pa(xen_io_tlb_start), PAGE_ALIGN(bytes)); 223 if (early)
183 m = "Failed to get contiguous memory for DMA from Xen!\n"\ 224 free_bootmem(__pa(xen_io_tlb_start), PAGE_ALIGN(bytes));
184 "You either: don't have the permissions, do not have"\ 225 else {
185 " enough free memory under 4GB, or the hypervisor memory"\ 226 free_pages((unsigned long)xen_io_tlb_start, order);
186 "is too fragmented!"; 227 xen_io_tlb_start = NULL;
228 }
229 m_ret = XEN_SWIOTLB_EFIXUP;
187 goto error; 230 goto error;
188 } 231 }
189 start_dma_addr = xen_virt_to_bus(xen_io_tlb_start); 232 start_dma_addr = xen_virt_to_bus(xen_io_tlb_start);
190 swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs, verbose); 233 if (early) {
191 234 swiotlb_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs, verbose);
192 return; 235 rc = 0;
236 } else
237 rc = swiotlb_late_init_with_tbl(xen_io_tlb_start, xen_io_tlb_nslabs);
238 return rc;
193error: 239error:
194 if (repeat--) { 240 if (repeat--) {
195 xen_io_tlb_nslabs = max(1024UL, /* Min is 2MB */ 241 xen_io_tlb_nslabs = max(1024UL, /* Min is 2MB */
@@ -198,10 +244,13 @@ error:
198 (xen_io_tlb_nslabs << IO_TLB_SHIFT) >> 20); 244 (xen_io_tlb_nslabs << IO_TLB_SHIFT) >> 20);
199 goto retry; 245 goto retry;
200 } 246 }
201 xen_raw_printk("%s (rc:%d)", m, rc); 247 pr_err("%s (rc:%d)", xen_swiotlb_error(m_ret), rc);
202 panic("%s (rc:%d)", m, rc); 248 if (early)
249 panic("%s (rc:%d)", xen_swiotlb_error(m_ret), rc);
250 else
251 free_pages((unsigned long)xen_io_tlb_start, order);
252 return rc;
203} 253}
204
205void * 254void *
206xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, 255xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
207 dma_addr_t *dma_handle, gfp_t flags, 256 dma_addr_t *dma_handle, gfp_t flags,
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 03342728bf23..e5a0c13e2ad4 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -362,6 +362,7 @@ static int __devinit pcistub_init_device(struct pci_dev *dev)
362 else { 362 else {
363 dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); 363 dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n");
364 __pci_reset_function_locked(dev); 364 __pci_reset_function_locked(dev);
365 pci_restore_state(dev);
365 } 366 }
366 /* Now disable the device (this also ensures some private device 367 /* Now disable the device (this also ensures some private device
367 * data is setup before we export) 368 * data is setup before we export)
@@ -681,14 +682,14 @@ static pci_ers_result_t xen_pcibk_slot_reset(struct pci_dev *dev)
681 dev_err(&dev->dev, DRV_NAME " device is not connected or owned" 682 dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
682 " by HVM, kill it\n"); 683 " by HVM, kill it\n");
683 kill_domain_by_device(psdev); 684 kill_domain_by_device(psdev);
684 goto release; 685 goto end;
685 } 686 }
686 687
687 if (!test_bit(_XEN_PCIB_AERHANDLER, 688 if (!test_bit(_XEN_PCIB_AERHANDLER,
688 (unsigned long *)&psdev->pdev->sh_info->flags)) { 689 (unsigned long *)&psdev->pdev->sh_info->flags)) {
689 dev_err(&dev->dev, 690 dev_err(&dev->dev,
690 "guest with no AER driver should have been killed\n"); 691 "guest with no AER driver should have been killed\n");
691 goto release; 692 goto end;
692 } 693 }
693 result = common_process(psdev, 1, XEN_PCI_OP_aer_slotreset, result); 694 result = common_process(psdev, 1, XEN_PCI_OP_aer_slotreset, result);
694 695
@@ -698,9 +699,9 @@ static pci_ers_result_t xen_pcibk_slot_reset(struct pci_dev *dev)
698 "No AER slot_reset service or disconnected!\n"); 699 "No AER slot_reset service or disconnected!\n");
699 kill_domain_by_device(psdev); 700 kill_domain_by_device(psdev);
700 } 701 }
701release:
702 pcistub_device_put(psdev);
703end: 702end:
703 if (psdev)
704 pcistub_device_put(psdev);
704 up_write(&pcistub_sem); 705 up_write(&pcistub_sem);
705 return result; 706 return result;
706 707
@@ -739,14 +740,14 @@ static pci_ers_result_t xen_pcibk_mmio_enabled(struct pci_dev *dev)
739 dev_err(&dev->dev, DRV_NAME " device is not connected or owned" 740 dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
740 " by HVM, kill it\n"); 741 " by HVM, kill it\n");
741 kill_domain_by_device(psdev); 742 kill_domain_by_device(psdev);
742 goto release; 743 goto end;
743 } 744 }
744 745
745 if (!test_bit(_XEN_PCIB_AERHANDLER, 746 if (!test_bit(_XEN_PCIB_AERHANDLER,
746 (unsigned long *)&psdev->pdev->sh_info->flags)) { 747 (unsigned long *)&psdev->pdev->sh_info->flags)) {
747 dev_err(&dev->dev, 748 dev_err(&dev->dev,
748 "guest with no AER driver should have been killed\n"); 749 "guest with no AER driver should have been killed\n");
749 goto release; 750 goto end;
750 } 751 }
751 result = common_process(psdev, 1, XEN_PCI_OP_aer_mmio, result); 752 result = common_process(psdev, 1, XEN_PCI_OP_aer_mmio, result);
752 753
@@ -756,9 +757,9 @@ static pci_ers_result_t xen_pcibk_mmio_enabled(struct pci_dev *dev)
756 "No AER mmio_enabled service or disconnected!\n"); 757 "No AER mmio_enabled service or disconnected!\n");
757 kill_domain_by_device(psdev); 758 kill_domain_by_device(psdev);
758 } 759 }
759release:
760 pcistub_device_put(psdev);
761end: 760end:
761 if (psdev)
762 pcistub_device_put(psdev);
762 up_write(&pcistub_sem); 763 up_write(&pcistub_sem);
763 return result; 764 return result;
764} 765}
@@ -797,7 +798,7 @@ static pci_ers_result_t xen_pcibk_error_detected(struct pci_dev *dev,
797 dev_err(&dev->dev, DRV_NAME " device is not connected or owned" 798 dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
798 " by HVM, kill it\n"); 799 " by HVM, kill it\n");
799 kill_domain_by_device(psdev); 800 kill_domain_by_device(psdev);
800 goto release; 801 goto end;
801 } 802 }
802 803
803 /*Guest owns the device yet no aer handler regiested, kill guest*/ 804 /*Guest owns the device yet no aer handler regiested, kill guest*/
@@ -805,7 +806,7 @@ static pci_ers_result_t xen_pcibk_error_detected(struct pci_dev *dev,
805 (unsigned long *)&psdev->pdev->sh_info->flags)) { 806 (unsigned long *)&psdev->pdev->sh_info->flags)) {
806 dev_dbg(&dev->dev, "guest may have no aer driver, kill it\n"); 807 dev_dbg(&dev->dev, "guest may have no aer driver, kill it\n");
807 kill_domain_by_device(psdev); 808 kill_domain_by_device(psdev);
808 goto release; 809 goto end;
809 } 810 }
810 result = common_process(psdev, error, XEN_PCI_OP_aer_detected, result); 811 result = common_process(psdev, error, XEN_PCI_OP_aer_detected, result);
811 812
@@ -815,9 +816,9 @@ static pci_ers_result_t xen_pcibk_error_detected(struct pci_dev *dev,
815 "No AER error_detected service or disconnected!\n"); 816 "No AER error_detected service or disconnected!\n");
816 kill_domain_by_device(psdev); 817 kill_domain_by_device(psdev);
817 } 818 }
818release:
819 pcistub_device_put(psdev);
820end: 819end:
820 if (psdev)
821 pcistub_device_put(psdev);
821 up_write(&pcistub_sem); 822 up_write(&pcistub_sem);
822 return result; 823 return result;
823} 824}
@@ -851,7 +852,7 @@ static void xen_pcibk_error_resume(struct pci_dev *dev)
851 dev_err(&dev->dev, DRV_NAME " device is not connected or owned" 852 dev_err(&dev->dev, DRV_NAME " device is not connected or owned"
852 " by HVM, kill it\n"); 853 " by HVM, kill it\n");
853 kill_domain_by_device(psdev); 854 kill_domain_by_device(psdev);
854 goto release; 855 goto end;
855 } 856 }
856 857
857 if (!test_bit(_XEN_PCIB_AERHANDLER, 858 if (!test_bit(_XEN_PCIB_AERHANDLER,
@@ -859,13 +860,13 @@ static void xen_pcibk_error_resume(struct pci_dev *dev)
859 dev_err(&dev->dev, 860 dev_err(&dev->dev,
860 "guest with no AER driver should have been killed\n"); 861 "guest with no AER driver should have been killed\n");
861 kill_domain_by_device(psdev); 862 kill_domain_by_device(psdev);
862 goto release; 863 goto end;
863 } 864 }
864 common_process(psdev, 1, XEN_PCI_OP_aer_resume, 865 common_process(psdev, 1, XEN_PCI_OP_aer_resume,
865 PCI_ERS_RESULT_RECOVERED); 866 PCI_ERS_RESULT_RECOVERED);
866release:
867 pcistub_device_put(psdev);
868end: 867end:
868 if (psdev)
869 pcistub_device_put(psdev);
869 up_write(&pcistub_sem); 870 up_write(&pcistub_sem);
870 return; 871 return;
871} 872}
@@ -897,17 +898,41 @@ static inline int str_to_slot(const char *buf, int *domain, int *bus,
897 int *slot, int *func) 898 int *slot, int *func)
898{ 899{
899 int err; 900 int err;
901 char wc = '*';
900 902
901 err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func); 903 err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func);
902 if (err == 4) 904 switch (err) {
905 case 3:
906 *func = -1;
907 err = sscanf(buf, " %x:%x:%x.%c", domain, bus, slot, &wc);
908 break;
909 case 2:
910 *slot = *func = -1;
911 err = sscanf(buf, " %x:%x:*.%c", domain, bus, &wc);
912 if (err >= 2)
913 ++err;
914 break;
915 }
916 if (err == 4 && wc == '*')
903 return 0; 917 return 0;
904 else if (err < 0) 918 else if (err < 0)
905 return -EINVAL; 919 return -EINVAL;
906 920
907 /* try again without domain */ 921 /* try again without domain */
908 *domain = 0; 922 *domain = 0;
923 wc = '*';
909 err = sscanf(buf, " %x:%x.%x", bus, slot, func); 924 err = sscanf(buf, " %x:%x.%x", bus, slot, func);
910 if (err == 3) 925 switch (err) {
926 case 2:
927 *func = -1;
928 err = sscanf(buf, " %x:%x.%c", bus, slot, &wc);
929 break;
930 case 1:
931 *slot = *func = -1;
932 err = sscanf(buf, " %x:*.%c", bus, &wc) + 1;
933 break;
934 }
935 if (err == 3 && wc == '*')
911 return 0; 936 return 0;
912 937
913 return -EINVAL; 938 return -EINVAL;
@@ -930,6 +955,19 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func)
930{ 955{
931 struct pcistub_device_id *pci_dev_id; 956 struct pcistub_device_id *pci_dev_id;
932 unsigned long flags; 957 unsigned long flags;
958 int rc = 0;
959
960 if (slot < 0) {
961 for (slot = 0; !rc && slot < 32; ++slot)
962 rc = pcistub_device_id_add(domain, bus, slot, func);
963 return rc;
964 }
965
966 if (func < 0) {
967 for (func = 0; !rc && func < 8; ++func)
968 rc = pcistub_device_id_add(domain, bus, slot, func);
969 return rc;
970 }
933 971
934 pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL); 972 pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
935 if (!pci_dev_id) 973 if (!pci_dev_id)
@@ -952,15 +990,15 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func)
952static int pcistub_device_id_remove(int domain, int bus, int slot, int func) 990static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
953{ 991{
954 struct pcistub_device_id *pci_dev_id, *t; 992 struct pcistub_device_id *pci_dev_id, *t;
955 int devfn = PCI_DEVFN(slot, func);
956 int err = -ENOENT; 993 int err = -ENOENT;
957 unsigned long flags; 994 unsigned long flags;
958 995
959 spin_lock_irqsave(&device_ids_lock, flags); 996 spin_lock_irqsave(&device_ids_lock, flags);
960 list_for_each_entry_safe(pci_dev_id, t, &pcistub_device_ids, 997 list_for_each_entry_safe(pci_dev_id, t, &pcistub_device_ids,
961 slot_list) { 998 slot_list) {
962 if (pci_dev_id->domain == domain 999 if (pci_dev_id->domain == domain && pci_dev_id->bus == bus
963 && pci_dev_id->bus == bus && pci_dev_id->devfn == devfn) { 1000 && (slot < 0 || PCI_SLOT(pci_dev_id->devfn) == slot)
1001 && (func < 0 || PCI_FUNC(pci_dev_id->devfn) == func)) {
964 /* Don't break; here because it's possible the same 1002 /* Don't break; here because it's possible the same
965 * slot could be in the list more than once 1003 * slot could be in the list more than once
966 */ 1004 */
@@ -987,7 +1025,7 @@ static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg,
987 struct config_field *field; 1025 struct config_field *field;
988 1026
989 psdev = pcistub_device_find(domain, bus, slot, func); 1027 psdev = pcistub_device_find(domain, bus, slot, func);
990 if (!psdev || !psdev->dev) { 1028 if (!psdev) {
991 err = -ENODEV; 1029 err = -ENODEV;
992 goto out; 1030 goto out;
993 } 1031 }
@@ -1011,6 +1049,8 @@ static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg,
1011 if (err) 1049 if (err)
1012 kfree(field); 1050 kfree(field);
1013out: 1051out:
1052 if (psdev)
1053 pcistub_device_put(psdev);
1014 return err; 1054 return err;
1015} 1055}
1016 1056
@@ -1115,10 +1155,9 @@ static ssize_t pcistub_irq_handler_switch(struct device_driver *drv,
1115 1155
1116 err = str_to_slot(buf, &domain, &bus, &slot, &func); 1156 err = str_to_slot(buf, &domain, &bus, &slot, &func);
1117 if (err) 1157 if (err)
1118 goto out; 1158 return err;
1119 1159
1120 psdev = pcistub_device_find(domain, bus, slot, func); 1160 psdev = pcistub_device_find(domain, bus, slot, func);
1121
1122 if (!psdev) 1161 if (!psdev)
1123 goto out; 1162 goto out;
1124 1163
@@ -1134,6 +1173,8 @@ static ssize_t pcistub_irq_handler_switch(struct device_driver *drv,
1134 if (dev_data->isr_on) 1173 if (dev_data->isr_on)
1135 dev_data->ack_intr = 1; 1174 dev_data->ack_intr = 1;
1136out: 1175out:
1176 if (psdev)
1177 pcistub_device_put(psdev);
1137 if (!err) 1178 if (!err)
1138 err = count; 1179 err = count;
1139 return err; 1180 return err;
@@ -1216,15 +1257,16 @@ static ssize_t permissive_add(struct device_driver *drv, const char *buf,
1216 err = str_to_slot(buf, &domain, &bus, &slot, &func); 1257 err = str_to_slot(buf, &domain, &bus, &slot, &func);
1217 if (err) 1258 if (err)
1218 goto out; 1259 goto out;
1260 if (slot < 0 || func < 0) {
1261 err = -EINVAL;
1262 goto out;
1263 }
1219 psdev = pcistub_device_find(domain, bus, slot, func); 1264 psdev = pcistub_device_find(domain, bus, slot, func);
1220 if (!psdev) { 1265 if (!psdev) {
1221 err = -ENODEV; 1266 err = -ENODEV;
1222 goto out; 1267 goto out;
1223 } 1268 }
1224 if (!psdev->dev) { 1269
1225 err = -ENODEV;
1226 goto release;
1227 }
1228 dev_data = pci_get_drvdata(psdev->dev); 1270 dev_data = pci_get_drvdata(psdev->dev);
1229 /* the driver data for a device should never be null at this point */ 1271 /* the driver data for a device should never be null at this point */
1230 if (!dev_data) { 1272 if (!dev_data) {
@@ -1297,17 +1339,51 @@ static int __init pcistub_init(void)
1297 1339
1298 if (pci_devs_to_hide && *pci_devs_to_hide) { 1340 if (pci_devs_to_hide && *pci_devs_to_hide) {
1299 do { 1341 do {
1342 char wc = '*';
1343
1300 parsed = 0; 1344 parsed = 0;
1301 1345
1302 err = sscanf(pci_devs_to_hide + pos, 1346 err = sscanf(pci_devs_to_hide + pos,
1303 " (%x:%x:%x.%x) %n", 1347 " (%x:%x:%x.%x) %n",
1304 &domain, &bus, &slot, &func, &parsed); 1348 &domain, &bus, &slot, &func, &parsed);
1305 if (err != 4) { 1349 switch (err) {
1350 case 3:
1351 func = -1;
1352 err = sscanf(pci_devs_to_hide + pos,
1353 " (%x:%x:%x.%c) %n",
1354 &domain, &bus, &slot, &wc,
1355 &parsed);
1356 break;
1357 case 2:
1358 slot = func = -1;
1359 err = sscanf(pci_devs_to_hide + pos,
1360 " (%x:%x:*.%c) %n",
1361 &domain, &bus, &wc, &parsed) + 1;
1362 break;
1363 }
1364
1365 if (err != 4 || wc != '*') {
1306 domain = 0; 1366 domain = 0;
1367 wc = '*';
1307 err = sscanf(pci_devs_to_hide + pos, 1368 err = sscanf(pci_devs_to_hide + pos,
1308 " (%x:%x.%x) %n", 1369 " (%x:%x.%x) %n",
1309 &bus, &slot, &func, &parsed); 1370 &bus, &slot, &func, &parsed);
1310 if (err != 3) 1371 switch (err) {
1372 case 2:
1373 func = -1;
1374 err = sscanf(pci_devs_to_hide + pos,
1375 " (%x:%x.%c) %n",
1376 &bus, &slot, &wc,
1377 &parsed);
1378 break;
1379 case 1:
1380 slot = func = -1;
1381 err = sscanf(pci_devs_to_hide + pos,
1382 " (%x:*.%c) %n",
1383 &bus, &wc, &parsed) + 1;
1384 break;
1385 }
1386 if (err != 3 || wc != '*')
1311 goto parse_error; 1387 goto parse_error;
1312 } 1388 }
1313 1389
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index b3e146edb51d..bcf3ba4a6ec1 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -490,8 +490,7 @@ static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev,
490 490
491 op.host_addr = arbitrary_virt_to_machine(pte).maddr; 491 op.host_addr = arbitrary_virt_to_machine(pte).maddr;
492 492
493 if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)) 493 gnttab_batch_map(&op, 1);
494 BUG();
495 494
496 if (op.status != GNTST_okay) { 495 if (op.status != GNTST_okay) {
497 free_vm_area(area); 496 free_vm_area(area);
@@ -572,8 +571,7 @@ int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
572 gnttab_set_map_op(&op, (unsigned long)vaddr, GNTMAP_host_map, gnt_ref, 571 gnttab_set_map_op(&op, (unsigned long)vaddr, GNTMAP_host_map, gnt_ref,
573 dev->otherend_id); 572 dev->otherend_id);
574 573
575 if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)) 574 gnttab_batch_map(&op, 1);
576 BUG();
577 575
578 if (op.status != GNTST_okay) { 576 if (op.status != GNTST_okay) {
579 xenbus_dev_fatal(dev, op.status, 577 xenbus_dev_fatal(dev, op.status,
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index e872526fdc5f..8d08b3ed406d 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -25,6 +25,7 @@ extern int swiotlb_force;
25extern void swiotlb_init(int verbose); 25extern void swiotlb_init(int verbose);
26extern void swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose); 26extern void swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose);
27extern unsigned long swiotlb_nr_tbl(void); 27extern unsigned long swiotlb_nr_tbl(void);
28extern int swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs);
28 29
29/* 30/*
30 * Enumeration for sync targets 31 * Enumeration for sync targets
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index 11e27c3af3cb..ba0d77529a29 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -189,4 +189,16 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
189int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops, 189int gnttab_unmap_refs(struct gnttab_unmap_grant_ref *unmap_ops,
190 struct page **pages, unsigned int count, bool clear_pte); 190 struct page **pages, unsigned int count, bool clear_pte);
191 191
192/* Perform a batch of grant map/copy operations. Retry every batch slot
193 * for which the hypervisor returns GNTST_eagain. This is typically due
194 * to paged out target frames.
195 *
196 * Will retry for 1, 2, ... 255 ms, i.e. 256 times during 32 seconds.
197 *
198 * Return value in each iand every status field of the batch guaranteed
199 * to not be GNTST_eagain.
200 */
201void gnttab_batch_map(struct gnttab_map_grant_ref *batch, unsigned count);
202void gnttab_batch_copy(struct gnttab_copy *batch, unsigned count);
203
192#endif /* __ASM_GNTTAB_H__ */ 204#endif /* __ASM_GNTTAB_H__ */
diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h
index a3275a850e54..54ad6f9e4725 100644
--- a/include/xen/interface/platform.h
+++ b/include/xen/interface/platform.h
@@ -112,6 +112,7 @@ DEFINE_GUEST_HANDLE_STRUCT(xenpf_platform_quirk_t);
112#define XEN_FW_DISK_INFO 1 /* from int 13 AH=08/41/48 */ 112#define XEN_FW_DISK_INFO 1 /* from int 13 AH=08/41/48 */
113#define XEN_FW_DISK_MBR_SIGNATURE 2 /* from MBR offset 0x1b8 */ 113#define XEN_FW_DISK_MBR_SIGNATURE 2 /* from MBR offset 0x1b8 */
114#define XEN_FW_VBEDDC_INFO 3 /* from int 10 AX=4f15 */ 114#define XEN_FW_VBEDDC_INFO 3 /* from int 10 AX=4f15 */
115#define XEN_FW_KBD_SHIFT_FLAGS 5 /* Int16, Fn02: Get keyboard shift flags. */
115struct xenpf_firmware_info { 116struct xenpf_firmware_info {
116 /* IN variables. */ 117 /* IN variables. */
117 uint32_t type; 118 uint32_t type;
@@ -142,6 +143,8 @@ struct xenpf_firmware_info {
142 /* must refer to 128-byte buffer */ 143 /* must refer to 128-byte buffer */
143 GUEST_HANDLE(uchar) edid; 144 GUEST_HANDLE(uchar) edid;
144 } vbeddc_info; /* XEN_FW_VBEDDC_INFO */ 145 } vbeddc_info; /* XEN_FW_VBEDDC_INFO */
146
147 uint8_t kbd_shift_flags; /* XEN_FW_KBD_SHIFT_FLAGS */
145 } u; 148 } u;
146}; 149};
147DEFINE_GUEST_HANDLE_STRUCT(xenpf_firmware_info_t); 150DEFINE_GUEST_HANDLE_STRUCT(xenpf_firmware_info_t);
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h
index 1e0df6b7d3b3..886a5d80a18f 100644
--- a/include/xen/interface/xen.h
+++ b/include/xen/interface/xen.h
@@ -454,6 +454,7 @@ struct dom0_vga_console_info {
454 uint8_t video_type; 454 uint8_t video_type;
455#define XEN_VGATYPE_TEXT_MODE_3 0x03 455#define XEN_VGATYPE_TEXT_MODE_3 0x03
456#define XEN_VGATYPE_VESA_LFB 0x23 456#define XEN_VGATYPE_VESA_LFB 0x23
457#define XEN_VGATYPE_EFI_LFB 0x70
457 458
458 union { 459 union {
459 struct { 460 struct {
diff --git a/include/xen/swiotlb-xen.h b/include/xen/swiotlb-xen.h
index c050b6b9de38..de8bcc641c49 100644
--- a/include/xen/swiotlb-xen.h
+++ b/include/xen/swiotlb-xen.h
@@ -3,7 +3,7 @@
3 3
4#include <linux/swiotlb.h> 4#include <linux/swiotlb.h>
5 5
6extern void xen_swiotlb_init(int verbose); 6extern int xen_swiotlb_init(int verbose, bool early);
7 7
8extern void 8extern void
9*xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size, 9*xen_swiotlb_alloc_coherent(struct device *hwdev, size_t size,
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 45bc1f83a5ad..f114bf6a8e13 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -170,7 +170,7 @@ void __init swiotlb_init_with_tbl(char *tlb, unsigned long nslabs, int verbose)
170 * Statically reserve bounce buffer space and initialize bounce buffer data 170 * Statically reserve bounce buffer space and initialize bounce buffer data
171 * structures for the software IO TLB used to implement the DMA API. 171 * structures for the software IO TLB used to implement the DMA API.
172 */ 172 */
173void __init 173static void __init
174swiotlb_init_with_default_size(size_t default_size, int verbose) 174swiotlb_init_with_default_size(size_t default_size, int verbose)
175{ 175{
176 unsigned long bytes; 176 unsigned long bytes;
@@ -206,8 +206,9 @@ swiotlb_init(int verbose)
206int 206int
207swiotlb_late_init_with_default_size(size_t default_size) 207swiotlb_late_init_with_default_size(size_t default_size)
208{ 208{
209 unsigned long i, bytes, req_nslabs = io_tlb_nslabs; 209 unsigned long bytes, req_nslabs = io_tlb_nslabs;
210 unsigned int order; 210 unsigned int order;
211 int rc = 0;
211 212
212 if (!io_tlb_nslabs) { 213 if (!io_tlb_nslabs) {
213 io_tlb_nslabs = (default_size >> IO_TLB_SHIFT); 214 io_tlb_nslabs = (default_size >> IO_TLB_SHIFT);
@@ -229,16 +230,32 @@ swiotlb_late_init_with_default_size(size_t default_size)
229 order--; 230 order--;
230 } 231 }
231 232
232 if (!io_tlb_start) 233 if (!io_tlb_start) {
233 goto cleanup1; 234 io_tlb_nslabs = req_nslabs;
234 235 return -ENOMEM;
236 }
235 if (order != get_order(bytes)) { 237 if (order != get_order(bytes)) {
236 printk(KERN_WARNING "Warning: only able to allocate %ld MB " 238 printk(KERN_WARNING "Warning: only able to allocate %ld MB "
237 "for software IO TLB\n", (PAGE_SIZE << order) >> 20); 239 "for software IO TLB\n", (PAGE_SIZE << order) >> 20);
238 io_tlb_nslabs = SLABS_PER_PAGE << order; 240 io_tlb_nslabs = SLABS_PER_PAGE << order;
239 bytes = io_tlb_nslabs << IO_TLB_SHIFT;
240 } 241 }
242 rc = swiotlb_late_init_with_tbl(io_tlb_start, io_tlb_nslabs);
243 if (rc)
244 free_pages((unsigned long)io_tlb_start, order);
245 return rc;
246}
247
248int
249swiotlb_late_init_with_tbl(char *tlb, unsigned long nslabs)
250{
251 unsigned long i, bytes;
252
253 bytes = nslabs << IO_TLB_SHIFT;
254
255 io_tlb_nslabs = nslabs;
256 io_tlb_start = tlb;
241 io_tlb_end = io_tlb_start + bytes; 257 io_tlb_end = io_tlb_start + bytes;
258
242 memset(io_tlb_start, 0, bytes); 259 memset(io_tlb_start, 0, bytes);
243 260
244 /* 261 /*
@@ -288,10 +305,8 @@ cleanup3:
288 io_tlb_list = NULL; 305 io_tlb_list = NULL;
289cleanup2: 306cleanup2:
290 io_tlb_end = NULL; 307 io_tlb_end = NULL;
291 free_pages((unsigned long)io_tlb_start, order);
292 io_tlb_start = NULL; 308 io_tlb_start = NULL;
293cleanup1: 309 io_tlb_nslabs = 0;
294 io_tlb_nslabs = req_nslabs;
295 return -ENOMEM; 310 return -ENOMEM;
296} 311}
297 312