aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/xen/interface.h1
-rw-r--r--arch/arm/xen/enlighten.c123
-rw-r--r--arch/x86/include/asm/xen/interface.h1
-rw-r--r--arch/x86/xen/Kconfig1
-rw-r--r--arch/x86/xen/enlighten.c102
-rw-r--r--arch/x86/xen/mmu.c17
-rw-r--r--arch/x86/xen/suspend.c2
-rw-r--r--arch/x86/xen/xen-ops.h2
-rw-r--r--drivers/xen/Kconfig3
-rw-r--r--drivers/xen/Makefile7
-rw-r--r--drivers/xen/balloon.c5
-rw-r--r--drivers/xen/privcmd.c72
-rw-r--r--drivers/xen/xen-acpi-pad.c182
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c118
-rw-r--r--drivers/xen/xenbus/xenbus_xs.c1
-rw-r--r--include/xen/interface/memory.h44
-rw-r--r--include/xen/interface/platform.h17
-rw-r--r--include/xen/xen-ops.h9
18 files changed, 591 insertions, 116 deletions
diff --git a/arch/arm/include/asm/xen/interface.h b/arch/arm/include/asm/xen/interface.h
index 5000397134b4..1151188bcd83 100644
--- a/arch/arm/include/asm/xen/interface.h
+++ b/arch/arm/include/asm/xen/interface.h
@@ -49,6 +49,7 @@ DEFINE_GUEST_HANDLE(void);
49DEFINE_GUEST_HANDLE(uint64_t); 49DEFINE_GUEST_HANDLE(uint64_t);
50DEFINE_GUEST_HANDLE(uint32_t); 50DEFINE_GUEST_HANDLE(uint32_t);
51DEFINE_GUEST_HANDLE(xen_pfn_t); 51DEFINE_GUEST_HANDLE(xen_pfn_t);
52DEFINE_GUEST_HANDLE(xen_ulong_t);
52 53
53/* Maximum number of virtual CPUs in multi-processor guests. */ 54/* Maximum number of virtual CPUs in multi-processor guests. */
54#define MAX_VIRT_CPUS 1 55#define MAX_VIRT_CPUS 1
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index f57609275449..7a32976fa2a3 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -8,6 +8,8 @@
8#include <xen/features.h> 8#include <xen/features.h>
9#include <xen/platform_pci.h> 9#include <xen/platform_pci.h>
10#include <xen/xenbus.h> 10#include <xen/xenbus.h>
11#include <xen/page.h>
12#include <xen/xen-ops.h>
11#include <asm/xen/hypervisor.h> 13#include <asm/xen/hypervisor.h>
12#include <asm/xen/hypercall.h> 14#include <asm/xen/hypercall.h>
13#include <linux/interrupt.h> 15#include <linux/interrupt.h>
@@ -17,6 +19,8 @@
17#include <linux/of_irq.h> 19#include <linux/of_irq.h>
18#include <linux/of_address.h> 20#include <linux/of_address.h>
19 21
22#include <linux/mm.h>
23
20struct start_info _xen_start_info; 24struct start_info _xen_start_info;
21struct start_info *xen_start_info = &_xen_start_info; 25struct start_info *xen_start_info = &_xen_start_info;
22EXPORT_SYMBOL_GPL(xen_start_info); 26EXPORT_SYMBOL_GPL(xen_start_info);
@@ -29,6 +33,10 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
29 33
30DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); 34DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
31 35
36/* These are unused until we support booting "pre-ballooned" */
37unsigned long xen_released_pages;
38struct xen_memory_region xen_extra_mem[XEN_EXTRA_MEM_MAX_REGIONS] __initdata;
39
32/* TODO: to be removed */ 40/* TODO: to be removed */
33__read_mostly int xen_have_vector_callback; 41__read_mostly int xen_have_vector_callback;
34EXPORT_SYMBOL_GPL(xen_have_vector_callback); 42EXPORT_SYMBOL_GPL(xen_have_vector_callback);
@@ -38,15 +46,106 @@ EXPORT_SYMBOL_GPL(xen_platform_pci_unplug);
38 46
39static __read_mostly int xen_events_irq = -1; 47static __read_mostly int xen_events_irq = -1;
40 48
49/* map fgmfn of domid to lpfn in the current domain */
50static int map_foreign_page(unsigned long lpfn, unsigned long fgmfn,
51 unsigned int domid)
52{
53 int rc;
54 struct xen_add_to_physmap_range xatp = {
55 .domid = DOMID_SELF,
56 .foreign_domid = domid,
57 .size = 1,
58 .space = XENMAPSPACE_gmfn_foreign,
59 };
60 xen_ulong_t idx = fgmfn;
61 xen_pfn_t gpfn = lpfn;
62
63 set_xen_guest_handle(xatp.idxs, &idx);
64 set_xen_guest_handle(xatp.gpfns, &gpfn);
65
66 rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
67 if (rc) {
68 pr_warn("Failed to map pfn to mfn rc:%d pfn:%lx mfn:%lx\n",
69 rc, lpfn, fgmfn);
70 return 1;
71 }
72 return 0;
73}
74
75struct remap_data {
76 xen_pfn_t fgmfn; /* foreign domain's gmfn */
77 pgprot_t prot;
78 domid_t domid;
79 struct vm_area_struct *vma;
80 int index;
81 struct page **pages;
82 struct xen_remap_mfn_info *info;
83};
84
85static int remap_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr,
86 void *data)
87{
88 struct remap_data *info = data;
89 struct page *page = info->pages[info->index++];
90 unsigned long pfn = page_to_pfn(page);
91 pte_t pte = pfn_pte(pfn, info->prot);
92
93 if (map_foreign_page(pfn, info->fgmfn, info->domid))
94 return -EFAULT;
95 set_pte_at(info->vma->vm_mm, addr, ptep, pte);
96
97 return 0;
98}
99
41int xen_remap_domain_mfn_range(struct vm_area_struct *vma, 100int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
42 unsigned long addr, 101 unsigned long addr,
43 unsigned long mfn, int nr, 102 xen_pfn_t mfn, int nr,
44 pgprot_t prot, unsigned domid) 103 pgprot_t prot, unsigned domid,
104 struct page **pages)
45{ 105{
46 return -ENOSYS; 106 int err;
107 struct remap_data data;
108
109 /* TBD: Batching, current sole caller only does page at a time */
110 if (nr > 1)
111 return -EINVAL;
112
113 data.fgmfn = mfn;
114 data.prot = prot;
115 data.domid = domid;
116 data.vma = vma;
117 data.index = 0;
118 data.pages = pages;
119 err = apply_to_page_range(vma->vm_mm, addr, nr << PAGE_SHIFT,
120 remap_pte_fn, &data);
121 return err;
47} 122}
48EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range); 123EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
49 124
125int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
126 int nr, struct page **pages)
127{
128 int i;
129
130 for (i = 0; i < nr; i++) {
131 struct xen_remove_from_physmap xrp;
132 unsigned long rc, pfn;
133
134 pfn = page_to_pfn(pages[i]);
135
136 xrp.domid = DOMID_SELF;
137 xrp.gpfn = pfn;
138 rc = HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp);
139 if (rc) {
140 pr_warn("Failed to unmap pfn:%lx rc:%ld\n",
141 pfn, rc);
142 return rc;
143 }
144 }
145 return 0;
146}
147EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
148
50/* 149/*
51 * see Documentation/devicetree/bindings/arm/xen.txt for the 150 * see Documentation/devicetree/bindings/arm/xen.txt for the
52 * documentation of the Xen Device Tree format. 151 * documentation of the Xen Device Tree format.
@@ -149,24 +248,6 @@ static int __init xen_init_events(void)
149} 248}
150postcore_initcall(xen_init_events); 249postcore_initcall(xen_init_events);
151 250
152/* XXX: only until balloon is properly working */
153int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
154{
155 *pages = alloc_pages(highmem ? GFP_HIGHUSER : GFP_KERNEL,
156 get_order(nr_pages));
157 if (*pages == NULL)
158 return -ENOMEM;
159 return 0;
160}
161EXPORT_SYMBOL_GPL(alloc_xenballooned_pages);
162
163void free_xenballooned_pages(int nr_pages, struct page **pages)
164{
165 kfree(*pages);
166 *pages = NULL;
167}
168EXPORT_SYMBOL_GPL(free_xenballooned_pages);
169
170/* In the hypervisor.S file. */ 251/* In the hypervisor.S file. */
171EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op); 252EXPORT_SYMBOL_GPL(HYPERVISOR_event_channel_op);
172EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op); 253EXPORT_SYMBOL_GPL(HYPERVISOR_grant_table_op);
diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xen/interface.h
index 54d52ff1304a..fd9cb7695b5f 100644
--- a/arch/x86/include/asm/xen/interface.h
+++ b/arch/x86/include/asm/xen/interface.h
@@ -63,6 +63,7 @@ DEFINE_GUEST_HANDLE(void);
63DEFINE_GUEST_HANDLE(uint64_t); 63DEFINE_GUEST_HANDLE(uint64_t);
64DEFINE_GUEST_HANDLE(uint32_t); 64DEFINE_GUEST_HANDLE(uint32_t);
65DEFINE_GUEST_HANDLE(xen_pfn_t); 65DEFINE_GUEST_HANDLE(xen_pfn_t);
66DEFINE_GUEST_HANDLE(xen_ulong_t);
66#endif 67#endif
67 68
68#ifndef HYPERVISOR_VIRT_START 69#ifndef HYPERVISOR_VIRT_START
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index 9a6775c9ddca..131dacd2748a 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -6,6 +6,7 @@ config XEN
6 bool "Xen guest support" 6 bool "Xen guest support"
7 select PARAVIRT 7 select PARAVIRT
8 select PARAVIRT_CLOCK 8 select PARAVIRT_CLOCK
9 select XEN_HAVE_PVMMU
9 depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS) 10 depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
10 depends on X86_TSC 11 depends on X86_TSC
11 help 12 help
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 586d83812b67..3aeaa933b527 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -223,6 +223,21 @@ static void __init xen_banner(void)
223 version >> 16, version & 0xffff, extra.extraversion, 223 version >> 16, version & 0xffff, extra.extraversion,
224 xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); 224 xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : "");
225} 225}
226/* Check if running on Xen version (major, minor) or later */
227bool
228xen_running_on_version_or_later(unsigned int major, unsigned int minor)
229{
230 unsigned int version;
231
232 if (!xen_domain())
233 return false;
234
235 version = HYPERVISOR_xen_version(XENVER_version, NULL);
236 if ((((version >> 16) == major) && ((version & 0xffff) >= minor)) ||
237 ((version >> 16) > major))
238 return true;
239 return false;
240}
226 241
227#define CPUID_THERM_POWER_LEAF 6 242#define CPUID_THERM_POWER_LEAF 6
228#define APERFMPERF_PRESENT 0 243#define APERFMPERF_PRESENT 0
@@ -287,8 +302,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
287 302
288static bool __init xen_check_mwait(void) 303static bool __init xen_check_mwait(void)
289{ 304{
290#if defined(CONFIG_ACPI) && !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) && \ 305#ifdef CONFIG_ACPI
291 !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE)
292 struct xen_platform_op op = { 306 struct xen_platform_op op = {
293 .cmd = XENPF_set_processor_pminfo, 307 .cmd = XENPF_set_processor_pminfo,
294 .u.set_pminfo.id = -1, 308 .u.set_pminfo.id = -1,
@@ -309,6 +323,13 @@ static bool __init xen_check_mwait(void)
309 if (!xen_initial_domain()) 323 if (!xen_initial_domain())
310 return false; 324 return false;
311 325
326 /*
327 * When running under platform earlier than Xen4.2, do not expose
328 * mwait, to avoid the risk of loading native acpi pad driver
329 */
330 if (!xen_running_on_version_or_later(4, 2))
331 return false;
332
312 ax = 1; 333 ax = 1;
313 cx = 0; 334 cx = 0;
314 335
@@ -1495,51 +1516,72 @@ asmlinkage void __init xen_start_kernel(void)
1495#endif 1516#endif
1496} 1517}
1497 1518
1498void __ref xen_hvm_init_shared_info(void) 1519#ifdef CONFIG_XEN_PVHVM
1520#define HVM_SHARED_INFO_ADDR 0xFE700000UL
1521static struct shared_info *xen_hvm_shared_info;
1522static unsigned long xen_hvm_sip_phys;
1523static int xen_major, xen_minor;
1524
1525static void xen_hvm_connect_shared_info(unsigned long pfn)
1499{ 1526{
1500 int cpu;
1501 struct xen_add_to_physmap xatp; 1527 struct xen_add_to_physmap xatp;
1502 static struct shared_info *shared_info_page = 0;
1503 1528
1504 if (!shared_info_page)
1505 shared_info_page = (struct shared_info *)
1506 extend_brk(PAGE_SIZE, PAGE_SIZE);
1507 xatp.domid = DOMID_SELF; 1529 xatp.domid = DOMID_SELF;
1508 xatp.idx = 0; 1530 xatp.idx = 0;
1509 xatp.space = XENMAPSPACE_shared_info; 1531 xatp.space = XENMAPSPACE_shared_info;
1510 xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT; 1532 xatp.gpfn = pfn;
1511 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) 1533 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
1512 BUG(); 1534 BUG();
1513 1535
1514 HYPERVISOR_shared_info = (struct shared_info *)shared_info_page; 1536}
1537static void __init xen_hvm_set_shared_info(struct shared_info *sip)
1538{
1539 int cpu;
1540
1541 HYPERVISOR_shared_info = sip;
1515 1542
1516 /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info 1543 /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
1517 * page, we use it in the event channel upcall and in some pvclock 1544 * page, we use it in the event channel upcall and in some pvclock
1518 * related functions. We don't need the vcpu_info placement 1545 * related functions. We don't need the vcpu_info placement
1519 * optimizations because we don't use any pv_mmu or pv_irq op on 1546 * optimizations because we don't use any pv_mmu or pv_irq op on
1520 * HVM. 1547 * HVM. */
1521 * When xen_hvm_init_shared_info is run at boot time only vcpu 0 is 1548 for_each_online_cpu(cpu)
1522 * online but xen_hvm_init_shared_info is run at resume time too and
1523 * in that case multiple vcpus might be online. */
1524 for_each_online_cpu(cpu) {
1525 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; 1549 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
1550}
1551
1552/* Reconnect the shared_info pfn to a (new) mfn */
1553void xen_hvm_resume_shared_info(void)
1554{
1555 xen_hvm_connect_shared_info(xen_hvm_sip_phys >> PAGE_SHIFT);
1556}
1557
1558/* Xen tools prior to Xen 4 do not provide a E820_Reserved area for guest usage.
1559 * On these old tools the shared info page will be placed in E820_Ram.
1560 * Xen 4 provides a E820_Reserved area at 0xFC000000, and this code expects
1561 * that nothing is mapped up to HVM_SHARED_INFO_ADDR.
1562 * Xen 4.3+ provides an explicit 1MB area at HVM_SHARED_INFO_ADDR which is used
1563 * here for the shared info page. */
1564static void __init xen_hvm_init_shared_info(void)
1565{
1566 if (xen_major < 4) {
1567 xen_hvm_shared_info = extend_brk(PAGE_SIZE, PAGE_SIZE);
1568 xen_hvm_sip_phys = __pa(xen_hvm_shared_info);
1569 } else {
1570 xen_hvm_sip_phys = HVM_SHARED_INFO_ADDR;
1571 set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_hvm_sip_phys);
1572 xen_hvm_shared_info =
1573 (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
1526 } 1574 }
1575 xen_hvm_connect_shared_info(xen_hvm_sip_phys >> PAGE_SHIFT);
1576 xen_hvm_set_shared_info(xen_hvm_shared_info);
1527} 1577}
1528 1578
1529#ifdef CONFIG_XEN_PVHVM
1530static void __init init_hvm_pv_info(void) 1579static void __init init_hvm_pv_info(void)
1531{ 1580{
1532 int major, minor; 1581 uint32_t ecx, edx, pages, msr, base;
1533 uint32_t eax, ebx, ecx, edx, pages, msr, base;
1534 u64 pfn; 1582 u64 pfn;
1535 1583
1536 base = xen_cpuid_base(); 1584 base = xen_cpuid_base();
1537 cpuid(base + 1, &eax, &ebx, &ecx, &edx);
1538
1539 major = eax >> 16;
1540 minor = eax & 0xffff;
1541 printk(KERN_INFO "Xen version %d.%d.\n", major, minor);
1542
1543 cpuid(base + 2, &pages, &msr, &ecx, &edx); 1585 cpuid(base + 2, &pages, &msr, &ecx, &edx);
1544 1586
1545 pfn = __pa(hypercall_page); 1587 pfn = __pa(hypercall_page);
@@ -1590,12 +1632,22 @@ static void __init xen_hvm_guest_init(void)
1590 1632
1591static bool __init xen_hvm_platform(void) 1633static bool __init xen_hvm_platform(void)
1592{ 1634{
1635 uint32_t eax, ebx, ecx, edx, base;
1636
1593 if (xen_pv_domain()) 1637 if (xen_pv_domain())
1594 return false; 1638 return false;
1595 1639
1596 if (!xen_cpuid_base()) 1640 base = xen_cpuid_base();
1641 if (!base)
1597 return false; 1642 return false;
1598 1643
1644 cpuid(base + 1, &eax, &ebx, &ecx, &edx);
1645
1646 xen_major = eax >> 16;
1647 xen_minor = eax & 0xffff;
1648
1649 printk(KERN_INFO "Xen version %d.%d.\n", xen_major, xen_minor);
1650
1599 return true; 1651 return true;
1600} 1652}
1601 1653
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index dcf5f2dd91ec..01de35c77221 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -2497,8 +2497,10 @@ static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token,
2497 2497
2498int xen_remap_domain_mfn_range(struct vm_area_struct *vma, 2498int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
2499 unsigned long addr, 2499 unsigned long addr,
2500 unsigned long mfn, int nr, 2500 xen_pfn_t mfn, int nr,
2501 pgprot_t prot, unsigned domid) 2501 pgprot_t prot, unsigned domid,
2502 struct page **pages)
2503
2502{ 2504{
2503 struct remap_data rmd; 2505 struct remap_data rmd;
2504 struct mmu_update mmu_update[REMAP_BATCH_SIZE]; 2506 struct mmu_update mmu_update[REMAP_BATCH_SIZE];
@@ -2542,3 +2544,14 @@ out:
2542 return err; 2544 return err;
2543} 2545}
2544EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range); 2546EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
2547
2548/* Returns: 0 success */
2549int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
2550 int numpgs, struct page **pages)
2551{
2552 if (!pages || !xen_feature(XENFEAT_auto_translated_physmap))
2553 return 0;
2554
2555 return -EINVAL;
2556}
2557EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
index 45329c8c226e..ae8a00c39de4 100644
--- a/arch/x86/xen/suspend.c
+++ b/arch/x86/xen/suspend.c
@@ -30,7 +30,7 @@ void xen_arch_hvm_post_suspend(int suspend_cancelled)
30{ 30{
31#ifdef CONFIG_XEN_PVHVM 31#ifdef CONFIG_XEN_PVHVM
32 int cpu; 32 int cpu;
33 xen_hvm_init_shared_info(); 33 xen_hvm_resume_shared_info();
34 xen_callback_vector(); 34 xen_callback_vector();
35 xen_unplug_emulated_devices(); 35 xen_unplug_emulated_devices();
36 if (xen_feature(XENFEAT_hvm_safe_pvclock)) { 36 if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index a95b41744ad0..d2e73d19d366 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -40,7 +40,7 @@ void xen_enable_syscall(void);
40void xen_vcpu_restore(void); 40void xen_vcpu_restore(void);
41 41
42void xen_callback_vector(void); 42void xen_callback_vector(void);
43void xen_hvm_init_shared_info(void); 43void xen_hvm_resume_shared_info(void);
44void xen_unplug_emulated_devices(void); 44void xen_unplug_emulated_devices(void);
45 45
46void __init xen_build_dynamic_phys_to_machine(void); 46void __init xen_build_dynamic_phys_to_machine(void);
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 126d8ce591ce..cabfa97f4674 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -206,4 +206,7 @@ config XEN_MCE_LOG
206 Allow kernel fetching MCE error from Xen platform and 206 Allow kernel fetching MCE error from Xen platform and
207 converting it into Linux mcelog format for mcelog tools 207 converting it into Linux mcelog format for mcelog tools
208 208
209config XEN_HAVE_PVMMU
210 bool
211
209endmenu 212endmenu
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 74354708c6c4..fb213cf81a7b 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -1,9 +1,9 @@
1ifneq ($(CONFIG_ARM),y) 1ifneq ($(CONFIG_ARM),y)
2obj-y += manage.o balloon.o 2obj-y += manage.o
3obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o 3obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o
4endif 4endif
5obj-$(CONFIG_X86) += fallback.o 5obj-$(CONFIG_X86) += fallback.o
6obj-y += grant-table.o features.o events.o 6obj-y += grant-table.o features.o events.o balloon.o
7obj-y += xenbus/ 7obj-y += xenbus/
8 8
9nostackp := $(call cc-option, -fno-stack-protector) 9nostackp := $(call cc-option, -fno-stack-protector)
@@ -11,7 +11,8 @@ CFLAGS_features.o := $(nostackp)
11 11
12dom0-$(CONFIG_PCI) += pci.o 12dom0-$(CONFIG_PCI) += pci.o
13dom0-$(CONFIG_USB_SUPPORT) += dbgp.o 13dom0-$(CONFIG_USB_SUPPORT) += dbgp.o
14dom0-$(CONFIG_ACPI) += acpi.o 14dom0-$(CONFIG_ACPI) += acpi.o $(xen-pad-y)
15xen-pad-$(CONFIG_X86) += xen-acpi-pad.o
15dom0-$(CONFIG_X86) += pcpu.o 16dom0-$(CONFIG_X86) += pcpu.o
16obj-$(CONFIG_XEN_DOM0) += $(dom0-y) 17obj-$(CONFIG_XEN_DOM0) += $(dom0-y)
17obj-$(CONFIG_BLOCK) += biomerge.o 18obj-$(CONFIG_BLOCK) += biomerge.o
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index d6886d90ccfd..a56776dbe095 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -359,6 +359,7 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
359 359
360 set_phys_to_machine(pfn, frame_list[i]); 360 set_phys_to_machine(pfn, frame_list[i]);
361 361
362#ifdef CONFIG_XEN_HAVE_PVMMU
362 /* Link back into the page tables if not highmem. */ 363 /* Link back into the page tables if not highmem. */
363 if (xen_pv_domain() && !PageHighMem(page)) { 364 if (xen_pv_domain() && !PageHighMem(page)) {
364 int ret; 365 int ret;
@@ -368,6 +369,7 @@ static enum bp_state increase_reservation(unsigned long nr_pages)
368 0); 369 0);
369 BUG_ON(ret); 370 BUG_ON(ret);
370 } 371 }
372#endif
371 373
372 /* Relinquish the page back to the allocator. */ 374 /* Relinquish the page back to the allocator. */
373 ClearPageReserved(page); 375 ClearPageReserved(page);
@@ -416,13 +418,14 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
416 418
417 scrub_page(page); 419 scrub_page(page);
418 420
421#ifdef CONFIG_XEN_HAVE_PVMMU
419 if (xen_pv_domain() && !PageHighMem(page)) { 422 if (xen_pv_domain() && !PageHighMem(page)) {
420 ret = HYPERVISOR_update_va_mapping( 423 ret = HYPERVISOR_update_va_mapping(
421 (unsigned long)__va(pfn << PAGE_SHIFT), 424 (unsigned long)__va(pfn << PAGE_SHIFT),
422 __pte_ma(0), 0); 425 __pte_ma(0), 0);
423 BUG_ON(ret); 426 BUG_ON(ret);
424 } 427 }
425 428#endif
426 } 429 }
427 430
428 /* Ensure that ballooned highmem pages don't have kmaps. */ 431 /* Ensure that ballooned highmem pages don't have kmaps. */
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index 71f5c459b088..0bbbccbb1f12 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -33,11 +33,14 @@
33#include <xen/features.h> 33#include <xen/features.h>
34#include <xen/page.h> 34#include <xen/page.h>
35#include <xen/xen-ops.h> 35#include <xen/xen-ops.h>
36#include <xen/balloon.h>
36 37
37#include "privcmd.h" 38#include "privcmd.h"
38 39
39MODULE_LICENSE("GPL"); 40MODULE_LICENSE("GPL");
40 41
42#define PRIV_VMA_LOCKED ((void *)1)
43
41#ifndef HAVE_ARCH_PRIVCMD_MMAP 44#ifndef HAVE_ARCH_PRIVCMD_MMAP
42static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma); 45static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma);
43#endif 46#endif
@@ -178,7 +181,7 @@ static int mmap_mfn_range(void *data, void *state)
178 msg->va & PAGE_MASK, 181 msg->va & PAGE_MASK,
179 msg->mfn, msg->npages, 182 msg->mfn, msg->npages,
180 vma->vm_page_prot, 183 vma->vm_page_prot,
181 st->domain); 184 st->domain, NULL);
182 if (rc < 0) 185 if (rc < 0)
183 return rc; 186 return rc;
184 187
@@ -199,6 +202,10 @@ static long privcmd_ioctl_mmap(void __user *udata)
199 if (!xen_initial_domain()) 202 if (!xen_initial_domain())
200 return -EPERM; 203 return -EPERM;
201 204
205 /* We only support privcmd_ioctl_mmap_batch for auto translated. */
206 if (xen_feature(XENFEAT_auto_translated_physmap))
207 return -ENOSYS;
208
202 if (copy_from_user(&mmapcmd, udata, sizeof(mmapcmd))) 209 if (copy_from_user(&mmapcmd, udata, sizeof(mmapcmd)))
203 return -EFAULT; 210 return -EFAULT;
204 211
@@ -246,6 +253,7 @@ struct mmap_batch_state {
246 domid_t domain; 253 domid_t domain;
247 unsigned long va; 254 unsigned long va;
248 struct vm_area_struct *vma; 255 struct vm_area_struct *vma;
256 int index;
249 /* A tristate: 257 /* A tristate:
250 * 0 for no errors 258 * 0 for no errors
251 * 1 if at least one error has happened (and no 259 * 1 if at least one error has happened (and no
@@ -260,14 +268,24 @@ struct mmap_batch_state {
260 xen_pfn_t __user *user_mfn; 268 xen_pfn_t __user *user_mfn;
261}; 269};
262 270
271/* auto translated dom0 note: if domU being created is PV, then mfn is
272 * mfn(addr on bus). If it's auto xlated, then mfn is pfn (input to HAP).
273 */
263static int mmap_batch_fn(void *data, void *state) 274static int mmap_batch_fn(void *data, void *state)
264{ 275{
265 xen_pfn_t *mfnp = data; 276 xen_pfn_t *mfnp = data;
266 struct mmap_batch_state *st = state; 277 struct mmap_batch_state *st = state;
278 struct vm_area_struct *vma = st->vma;
279 struct page **pages = vma->vm_private_data;
280 struct page *cur_page = NULL;
267 int ret; 281 int ret;
268 282
283 if (xen_feature(XENFEAT_auto_translated_physmap))
284 cur_page = pages[st->index++];
285
269 ret = xen_remap_domain_mfn_range(st->vma, st->va & PAGE_MASK, *mfnp, 1, 286 ret = xen_remap_domain_mfn_range(st->vma, st->va & PAGE_MASK, *mfnp, 1,
270 st->vma->vm_page_prot, st->domain); 287 st->vma->vm_page_prot, st->domain,
288 &cur_page);
271 289
272 /* Store error code for second pass. */ 290 /* Store error code for second pass. */
273 *(st->err++) = ret; 291 *(st->err++) = ret;
@@ -303,6 +321,32 @@ static int mmap_return_errors_v1(void *data, void *state)
303 return __put_user(*mfnp, st->user_mfn++); 321 return __put_user(*mfnp, st->user_mfn++);
304} 322}
305 323
324/* Allocate pfns that are then mapped with gmfns from foreign domid. Update
325 * the vma with the page info to use later.
326 * Returns: 0 if success, otherwise -errno
327 */
328static int alloc_empty_pages(struct vm_area_struct *vma, int numpgs)
329{
330 int rc;
331 struct page **pages;
332
333 pages = kcalloc(numpgs, sizeof(pages[0]), GFP_KERNEL);
334 if (pages == NULL)
335 return -ENOMEM;
336
337 rc = alloc_xenballooned_pages(numpgs, pages, 0);
338 if (rc != 0) {
339 pr_warn("%s Could not alloc %d pfns rc:%d\n", __func__,
340 numpgs, rc);
341 kfree(pages);
342 return -ENOMEM;
343 }
344 BUG_ON(vma->vm_private_data != PRIV_VMA_LOCKED);
345 vma->vm_private_data = pages;
346
347 return 0;
348}
349
306static struct vm_operations_struct privcmd_vm_ops; 350static struct vm_operations_struct privcmd_vm_ops;
307 351
308static long privcmd_ioctl_mmap_batch(void __user *udata, int version) 352static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
@@ -370,10 +414,18 @@ static long privcmd_ioctl_mmap_batch(void __user *udata, int version)
370 ret = -EINVAL; 414 ret = -EINVAL;
371 goto out; 415 goto out;
372 } 416 }
417 if (xen_feature(XENFEAT_auto_translated_physmap)) {
418 ret = alloc_empty_pages(vma, m.num);
419 if (ret < 0) {
420 up_write(&mm->mmap_sem);
421 goto out;
422 }
423 }
373 424
374 state.domain = m.dom; 425 state.domain = m.dom;
375 state.vma = vma; 426 state.vma = vma;
376 state.va = m.addr; 427 state.va = m.addr;
428 state.index = 0;
377 state.global_error = 0; 429 state.global_error = 0;
378 state.err = err_array; 430 state.err = err_array;
379 431
@@ -442,6 +494,19 @@ static long privcmd_ioctl(struct file *file,
442 return ret; 494 return ret;
443} 495}
444 496
497static void privcmd_close(struct vm_area_struct *vma)
498{
499 struct page **pages = vma->vm_private_data;
500 int numpgs = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
501
502 if (!xen_feature(XENFEAT_auto_translated_physmap || !numpgs || !pages))
503 return;
504
505 xen_unmap_domain_mfn_range(vma, numpgs, pages);
506 free_xenballooned_pages(numpgs, pages);
507 kfree(pages);
508}
509
445static int privcmd_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 510static int privcmd_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
446{ 511{
447 printk(KERN_DEBUG "privcmd_fault: vma=%p %lx-%lx, pgoff=%lx, uv=%p\n", 512 printk(KERN_DEBUG "privcmd_fault: vma=%p %lx-%lx, pgoff=%lx, uv=%p\n",
@@ -452,6 +517,7 @@ static int privcmd_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
452} 517}
453 518
454static struct vm_operations_struct privcmd_vm_ops = { 519static struct vm_operations_struct privcmd_vm_ops = {
520 .close = privcmd_close,
455 .fault = privcmd_fault 521 .fault = privcmd_fault
456}; 522};
457 523
@@ -469,7 +535,7 @@ static int privcmd_mmap(struct file *file, struct vm_area_struct *vma)
469 535
470static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma) 536static int privcmd_enforce_singleshot_mapping(struct vm_area_struct *vma)
471{ 537{
472 return (xchg(&vma->vm_private_data, (void *)1) == NULL); 538 return !cmpxchg(&vma->vm_private_data, NULL, PRIV_VMA_LOCKED);
473} 539}
474 540
475const struct file_operations xen_privcmd_fops = { 541const struct file_operations xen_privcmd_fops = {
diff --git a/drivers/xen/xen-acpi-pad.c b/drivers/xen/xen-acpi-pad.c
new file mode 100644
index 000000000000..da39191e7278
--- /dev/null
+++ b/drivers/xen/xen-acpi-pad.c
@@ -0,0 +1,182 @@
1/*
2 * xen-acpi-pad.c - Xen pad interface
3 *
4 * Copyright (c) 2012, Intel Corporation.
5 * Author: Liu, Jinsong <jinsong.liu@intel.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 */
16
17#include <linux/kernel.h>
18#include <linux/types.h>
19#include <acpi/acpi_bus.h>
20#include <acpi/acpi_drivers.h>
21#include <asm/xen/hypercall.h>
22#include <xen/interface/version.h>
23#include <xen/xen-ops.h>
24
25#define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad"
26#define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
27#define ACPI_PROCESSOR_AGGREGATOR_NOTIFY 0x80
28static DEFINE_MUTEX(xen_cpu_lock);
29
30static int xen_acpi_pad_idle_cpus(unsigned int idle_nums)
31{
32 struct xen_platform_op op;
33
34 op.cmd = XENPF_core_parking;
35 op.u.core_parking.type = XEN_CORE_PARKING_SET;
36 op.u.core_parking.idle_nums = idle_nums;
37
38 return HYPERVISOR_dom0_op(&op);
39}
40
41static int xen_acpi_pad_idle_cpus_num(void)
42{
43 struct xen_platform_op op;
44
45 op.cmd = XENPF_core_parking;
46 op.u.core_parking.type = XEN_CORE_PARKING_GET;
47
48 return HYPERVISOR_dom0_op(&op)
49 ?: op.u.core_parking.idle_nums;
50}
51
52/*
53 * Query firmware how many CPUs should be idle
54 * return -1 on failure
55 */
56static int acpi_pad_pur(acpi_handle handle)
57{
58 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
59 union acpi_object *package;
60 int num = -1;
61
62 if (ACPI_FAILURE(acpi_evaluate_object(handle, "_PUR", NULL, &buffer)))
63 return num;
64
65 if (!buffer.length || !buffer.pointer)
66 return num;
67
68 package = buffer.pointer;
69
70 if (package->type == ACPI_TYPE_PACKAGE &&
71 package->package.count == 2 &&
72 package->package.elements[0].integer.value == 1) /* rev 1 */
73 num = package->package.elements[1].integer.value;
74
75 kfree(buffer.pointer);
76 return num;
77}
78
79/* Notify firmware how many CPUs are idle */
80static void acpi_pad_ost(acpi_handle handle, int stat,
81 uint32_t idle_nums)
82{
83 union acpi_object params[3] = {
84 {.type = ACPI_TYPE_INTEGER,},
85 {.type = ACPI_TYPE_INTEGER,},
86 {.type = ACPI_TYPE_BUFFER,},
87 };
88 struct acpi_object_list arg_list = {3, params};
89
90 params[0].integer.value = ACPI_PROCESSOR_AGGREGATOR_NOTIFY;
91 params[1].integer.value = stat;
92 params[2].buffer.length = 4;
93 params[2].buffer.pointer = (void *)&idle_nums;
94 acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
95}
96
97static void acpi_pad_handle_notify(acpi_handle handle)
98{
99 int idle_nums;
100
101 mutex_lock(&xen_cpu_lock);
102 idle_nums = acpi_pad_pur(handle);
103 if (idle_nums < 0) {
104 mutex_unlock(&xen_cpu_lock);
105 return;
106 }
107
108 idle_nums = xen_acpi_pad_idle_cpus(idle_nums)
109 ?: xen_acpi_pad_idle_cpus_num();
110 if (idle_nums >= 0)
111 acpi_pad_ost(handle, 0, idle_nums);
112 mutex_unlock(&xen_cpu_lock);
113}
114
115static void acpi_pad_notify(acpi_handle handle, u32 event,
116 void *data)
117{
118 switch (event) {
119 case ACPI_PROCESSOR_AGGREGATOR_NOTIFY:
120 acpi_pad_handle_notify(handle);
121 break;
122 default:
123 pr_warn("Unsupported event [0x%x]\n", event);
124 break;
125 }
126}
127
128static int acpi_pad_add(struct acpi_device *device)
129{
130 acpi_status status;
131
132 strcpy(acpi_device_name(device), ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME);
133 strcpy(acpi_device_class(device), ACPI_PROCESSOR_AGGREGATOR_CLASS);
134
135 status = acpi_install_notify_handler(device->handle,
136 ACPI_DEVICE_NOTIFY, acpi_pad_notify, device);
137 if (ACPI_FAILURE(status))
138 return -ENODEV;
139
140 return 0;
141}
142
143static int acpi_pad_remove(struct acpi_device *device,
144 int type)
145{
146 mutex_lock(&xen_cpu_lock);
147 xen_acpi_pad_idle_cpus(0);
148 mutex_unlock(&xen_cpu_lock);
149
150 acpi_remove_notify_handler(device->handle,
151 ACPI_DEVICE_NOTIFY, acpi_pad_notify);
152 return 0;
153}
154
155static const struct acpi_device_id pad_device_ids[] = {
156 {"ACPI000C", 0},
157 {"", 0},
158};
159
160static struct acpi_driver acpi_pad_driver = {
161 .name = "processor_aggregator",
162 .class = ACPI_PROCESSOR_AGGREGATOR_CLASS,
163 .ids = pad_device_ids,
164 .ops = {
165 .add = acpi_pad_add,
166 .remove = acpi_pad_remove,
167 },
168};
169
170static int __init xen_acpi_pad_init(void)
171{
172 /* Only DOM0 is responsible for Xen acpi pad */
173 if (!xen_initial_domain())
174 return -ENODEV;
175
176 /* Only Xen4.2 or later support Xen acpi pad */
177 if (!xen_running_on_version_or_later(4, 2))
178 return -ENODEV;
179
180 return acpi_bus_register_driver(&acpi_pad_driver);
181}
182subsys_initcall(xen_acpi_pad_init);
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index 68dcc59cd287..cd50d251998e 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -142,7 +142,8 @@ static struct pcistub_device *pcistub_device_find(int domain, int bus,
142 if (psdev->dev != NULL 142 if (psdev->dev != NULL
143 && domain == pci_domain_nr(psdev->dev->bus) 143 && domain == pci_domain_nr(psdev->dev->bus)
144 && bus == psdev->dev->bus->number 144 && bus == psdev->dev->bus->number
145 && PCI_DEVFN(slot, func) == psdev->dev->devfn) { 145 && slot == PCI_SLOT(psdev->dev->devfn)
146 && func == PCI_FUNC(psdev->dev->devfn)) {
146 pcistub_device_get(psdev); 147 pcistub_device_get(psdev);
147 goto out; 148 goto out;
148 } 149 }
@@ -191,7 +192,8 @@ struct pci_dev *pcistub_get_pci_dev_by_slot(struct xen_pcibk_device *pdev,
191 if (psdev->dev != NULL 192 if (psdev->dev != NULL
192 && domain == pci_domain_nr(psdev->dev->bus) 193 && domain == pci_domain_nr(psdev->dev->bus)
193 && bus == psdev->dev->bus->number 194 && bus == psdev->dev->bus->number
194 && PCI_DEVFN(slot, func) == psdev->dev->devfn) { 195 && slot == PCI_SLOT(psdev->dev->devfn)
196 && func == PCI_FUNC(psdev->dev->devfn)) {
195 found_dev = pcistub_device_get_pci_dev(pdev, psdev); 197 found_dev = pcistub_device_get_pci_dev(pdev, psdev);
196 break; 198 break;
197 } 199 }
@@ -897,42 +899,35 @@ static struct pci_driver xen_pcibk_pci_driver = {
897static inline int str_to_slot(const char *buf, int *domain, int *bus, 899static inline int str_to_slot(const char *buf, int *domain, int *bus,
898 int *slot, int *func) 900 int *slot, int *func)
899{ 901{
900 int err; 902 int parsed = 0;
901 char wc = '*';
902 903
903 err = sscanf(buf, " %x:%x:%x.%x", domain, bus, slot, func); 904 switch (sscanf(buf, " %x:%x:%x.%x %n", domain, bus, slot, func,
904 switch (err) { 905 &parsed)) {
905 case 3: 906 case 3:
906 *func = -1; 907 *func = -1;
907 err = sscanf(buf, " %x:%x:%x.%c", domain, bus, slot, &wc); 908 sscanf(buf, " %x:%x:%x.* %n", domain, bus, slot, &parsed);
908 break; 909 break;
909 case 2: 910 case 2:
910 *slot = *func = -1; 911 *slot = *func = -1;
911 err = sscanf(buf, " %x:%x:*.%c", domain, bus, &wc); 912 sscanf(buf, " %x:%x:*.* %n", domain, bus, &parsed);
912 if (err >= 2)
913 ++err;
914 break; 913 break;
915 } 914 }
916 if (err == 4 && wc == '*') 915 if (parsed && !buf[parsed])
917 return 0; 916 return 0;
918 else if (err < 0)
919 return -EINVAL;
920 917
921 /* try again without domain */ 918 /* try again without domain */
922 *domain = 0; 919 *domain = 0;
923 wc = '*'; 920 switch (sscanf(buf, " %x:%x.%x %n", bus, slot, func, &parsed)) {
924 err = sscanf(buf, " %x:%x.%x", bus, slot, func);
925 switch (err) {
926 case 2: 921 case 2:
927 *func = -1; 922 *func = -1;
928 err = sscanf(buf, " %x:%x.%c", bus, slot, &wc); 923 sscanf(buf, " %x:%x.* %n", bus, slot, &parsed);
929 break; 924 break;
930 case 1: 925 case 1:
931 *slot = *func = -1; 926 *slot = *func = -1;
932 err = sscanf(buf, " %x:*.%c", bus, &wc) + 1; 927 sscanf(buf, " %x:*.* %n", bus, &parsed);
933 break; 928 break;
934 } 929 }
935 if (err == 3 && wc == '*') 930 if (parsed && !buf[parsed])
936 return 0; 931 return 0;
937 932
938 return -EINVAL; 933 return -EINVAL;
@@ -941,13 +936,20 @@ static inline int str_to_slot(const char *buf, int *domain, int *bus,
941static inline int str_to_quirk(const char *buf, int *domain, int *bus, int 936static inline int str_to_quirk(const char *buf, int *domain, int *bus, int
942 *slot, int *func, int *reg, int *size, int *mask) 937 *slot, int *func, int *reg, int *size, int *mask)
943{ 938{
944 int err; 939 int parsed = 0;
945 940
946 err = 941 sscanf(buf, " %x:%x:%x.%x-%x:%x:%x %n", domain, bus, slot, func,
947 sscanf(buf, " %04x:%02x:%02x.%d-%08x:%1x:%08x", domain, bus, slot, 942 reg, size, mask, &parsed);
948 func, reg, size, mask); 943 if (parsed && !buf[parsed])
949 if (err == 7)
950 return 0; 944 return 0;
945
946 /* try again without domain */
947 *domain = 0;
948 sscanf(buf, " %x:%x.%x-%x:%x:%x %n", bus, slot, func, reg, size,
949 mask, &parsed);
950 if (parsed && !buf[parsed])
951 return 0;
952
951 return -EINVAL; 953 return -EINVAL;
952} 954}
953 955
@@ -955,7 +957,7 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func)
955{ 957{
956 struct pcistub_device_id *pci_dev_id; 958 struct pcistub_device_id *pci_dev_id;
957 unsigned long flags; 959 unsigned long flags;
958 int rc = 0; 960 int rc = 0, devfn = PCI_DEVFN(slot, func);
959 961
960 if (slot < 0) { 962 if (slot < 0) {
961 for (slot = 0; !rc && slot < 32; ++slot) 963 for (slot = 0; !rc && slot < 32; ++slot)
@@ -969,13 +971,24 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func)
969 return rc; 971 return rc;
970 } 972 }
971 973
974 if ((
975#if !defined(MODULE) /* pci_domains_supported is not being exported */ \
976 || !defined(CONFIG_PCI_DOMAINS)
977 !pci_domains_supported ? domain :
978#endif
979 domain < 0 || domain > 0xffff)
980 || bus < 0 || bus > 0xff
981 || PCI_SLOT(devfn) != slot
982 || PCI_FUNC(devfn) != func)
983 return -EINVAL;
984
972 pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL); 985 pci_dev_id = kmalloc(sizeof(*pci_dev_id), GFP_KERNEL);
973 if (!pci_dev_id) 986 if (!pci_dev_id)
974 return -ENOMEM; 987 return -ENOMEM;
975 988
976 pci_dev_id->domain = domain; 989 pci_dev_id->domain = domain;
977 pci_dev_id->bus = bus; 990 pci_dev_id->bus = bus;
978 pci_dev_id->devfn = PCI_DEVFN(slot, func); 991 pci_dev_id->devfn = devfn;
979 992
980 pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%d\n", 993 pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%d\n",
981 domain, bus, slot, func); 994 domain, bus, slot, func);
@@ -1016,14 +1029,18 @@ static int pcistub_device_id_remove(int domain, int bus, int slot, int func)
1016 return err; 1029 return err;
1017} 1030}
1018 1031
1019static int pcistub_reg_add(int domain, int bus, int slot, int func, int reg, 1032static int pcistub_reg_add(int domain, int bus, int slot, int func,
1020 int size, int mask) 1033 unsigned int reg, unsigned int size,
1034 unsigned int mask)
1021{ 1035{
1022 int err = 0; 1036 int err = 0;
1023 struct pcistub_device *psdev; 1037 struct pcistub_device *psdev;
1024 struct pci_dev *dev; 1038 struct pci_dev *dev;
1025 struct config_field *field; 1039 struct config_field *field;
1026 1040
1041 if (reg > 0xfff || (size < 4 && (mask >> (size * 8))))
1042 return -EINVAL;
1043
1027 psdev = pcistub_device_find(domain, bus, slot, func); 1044 psdev = pcistub_device_find(domain, bus, slot, func);
1028 if (!psdev) { 1045 if (!psdev) {
1029 err = -ENODEV; 1046 err = -ENODEV;
@@ -1254,13 +1271,11 @@ static ssize_t permissive_add(struct device_driver *drv, const char *buf,
1254 int err; 1271 int err;
1255 struct pcistub_device *psdev; 1272 struct pcistub_device *psdev;
1256 struct xen_pcibk_dev_data *dev_data; 1273 struct xen_pcibk_dev_data *dev_data;
1274
1257 err = str_to_slot(buf, &domain, &bus, &slot, &func); 1275 err = str_to_slot(buf, &domain, &bus, &slot, &func);
1258 if (err) 1276 if (err)
1259 goto out; 1277 goto out;
1260 if (slot < 0 || func < 0) { 1278
1261 err = -EINVAL;
1262 goto out;
1263 }
1264 psdev = pcistub_device_find(domain, bus, slot, func); 1279 psdev = pcistub_device_find(domain, bus, slot, func);
1265 if (!psdev) { 1280 if (!psdev) {
1266 err = -ENODEV; 1281 err = -ENODEV;
@@ -1339,8 +1354,6 @@ static int __init pcistub_init(void)
1339 1354
1340 if (pci_devs_to_hide && *pci_devs_to_hide) { 1355 if (pci_devs_to_hide && *pci_devs_to_hide) {
1341 do { 1356 do {
1342 char wc = '*';
1343
1344 parsed = 0; 1357 parsed = 0;
1345 1358
1346 err = sscanf(pci_devs_to_hide + pos, 1359 err = sscanf(pci_devs_to_hide + pos,
@@ -1349,51 +1362,48 @@ static int __init pcistub_init(void)
1349 switch (err) { 1362 switch (err) {
1350 case 3: 1363 case 3:
1351 func = -1; 1364 func = -1;
1352 err = sscanf(pci_devs_to_hide + pos, 1365 sscanf(pci_devs_to_hide + pos,
1353 " (%x:%x:%x.%c) %n", 1366 " (%x:%x:%x.*) %n",
1354 &domain, &bus, &slot, &wc, 1367 &domain, &bus, &slot, &parsed);
1355 &parsed);
1356 break; 1368 break;
1357 case 2: 1369 case 2:
1358 slot = func = -1; 1370 slot = func = -1;
1359 err = sscanf(pci_devs_to_hide + pos, 1371 sscanf(pci_devs_to_hide + pos,
1360 " (%x:%x:*.%c) %n", 1372 " (%x:%x:*.*) %n",
1361 &domain, &bus, &wc, &parsed) + 1; 1373 &domain, &bus, &parsed);
1362 break; 1374 break;
1363 } 1375 }
1364 1376
1365 if (err != 4 || wc != '*') { 1377 if (!parsed) {
1366 domain = 0; 1378 domain = 0;
1367 wc = '*';
1368 err = sscanf(pci_devs_to_hide + pos, 1379 err = sscanf(pci_devs_to_hide + pos,
1369 " (%x:%x.%x) %n", 1380 " (%x:%x.%x) %n",
1370 &bus, &slot, &func, &parsed); 1381 &bus, &slot, &func, &parsed);
1371 switch (err) { 1382 switch (err) {
1372 case 2: 1383 case 2:
1373 func = -1; 1384 func = -1;
1374 err = sscanf(pci_devs_to_hide + pos, 1385 sscanf(pci_devs_to_hide + pos,
1375 " (%x:%x.%c) %n", 1386 " (%x:%x.*) %n",
1376 &bus, &slot, &wc, 1387 &bus, &slot, &parsed);
1377 &parsed);
1378 break; 1388 break;
1379 case 1: 1389 case 1:
1380 slot = func = -1; 1390 slot = func = -1;
1381 err = sscanf(pci_devs_to_hide + pos, 1391 sscanf(pci_devs_to_hide + pos,
1382 " (%x:*.%c) %n", 1392 " (%x:*.*) %n",
1383 &bus, &wc, &parsed) + 1; 1393 &bus, &parsed);
1384 break; 1394 break;
1385 } 1395 }
1386 if (err != 3 || wc != '*')
1387 goto parse_error;
1388 } 1396 }
1389 1397
1398 if (parsed <= 0)
1399 goto parse_error;
1400
1390 err = pcistub_device_id_add(domain, bus, slot, func); 1401 err = pcistub_device_id_add(domain, bus, slot, func);
1391 if (err) 1402 if (err)
1392 goto out; 1403 goto out;
1393 1404
1394 /* if parsed<=0, we've reached the end of the string */
1395 pos += parsed; 1405 pos += parsed;
1396 } while (parsed > 0 && pci_devs_to_hide[pos]); 1406 } while (pci_devs_to_hide[pos]);
1397 } 1407 }
1398 1408
1399 /* If we're the first PCI Device Driver to register, we're the 1409 /* If we're the first PCI Device Driver to register, we're the
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index acedeabe589c..88e677b0de74 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -48,7 +48,6 @@
48#include <xen/xenbus.h> 48#include <xen/xenbus.h>
49#include <xen/xen.h> 49#include <xen/xen.h>
50#include "xenbus_comms.h" 50#include "xenbus_comms.h"
51#include <asm/xen/hypervisor.h>
52 51
53struct xs_stored_msg { 52struct xs_stored_msg {
54 struct list_head list; 53 struct list_head list;
diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h
index 90712e2072d5..b40a4315cb8b 100644
--- a/include/xen/interface/memory.h
+++ b/include/xen/interface/memory.h
@@ -153,6 +153,14 @@ struct xen_machphys_mapping {
153}; 153};
154DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t); 154DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t);
155 155
156#define XENMAPSPACE_shared_info 0 /* shared info page */
157#define XENMAPSPACE_grant_table 1 /* grant table page */
158#define XENMAPSPACE_gmfn 2 /* GMFN */
159#define XENMAPSPACE_gmfn_range 3 /* GMFN range, XENMEM_add_to_physmap only. */
160#define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom,
161 * XENMEM_add_to_physmap_range only.
162 */
163
156/* 164/*
157 * Sets the GPFN at which a particular page appears in the specified guest's 165 * Sets the GPFN at which a particular page appears in the specified guest's
158 * pseudophysical address space. 166 * pseudophysical address space.
@@ -167,8 +175,6 @@ struct xen_add_to_physmap {
167 uint16_t size; 175 uint16_t size;
168 176
169 /* Source mapping space. */ 177 /* Source mapping space. */
170#define XENMAPSPACE_shared_info 0 /* shared info page */
171#define XENMAPSPACE_grant_table 1 /* grant table page */
172 unsigned int space; 178 unsigned int space;
173 179
174 /* Index into source mapping space. */ 180 /* Index into source mapping space. */
@@ -182,6 +188,24 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap);
182/*** REMOVED ***/ 188/*** REMOVED ***/
183/*#define XENMEM_translate_gpfn_list 8*/ 189/*#define XENMEM_translate_gpfn_list 8*/
184 190
191#define XENMEM_add_to_physmap_range 23
192struct xen_add_to_physmap_range {
193 /* Which domain to change the mapping for. */
194 domid_t domid;
195 uint16_t space; /* => enum phys_map_space */
196
197 /* Number of pages to go through */
198 uint16_t size;
199 domid_t foreign_domid; /* IFF gmfn_foreign */
200
201 /* Indexes into space being mapped. */
202 GUEST_HANDLE(xen_ulong_t) idxs;
203
204 /* GPFN in domid where the source mapping page should appear. */
205 GUEST_HANDLE(xen_pfn_t) gpfns;
206};
207DEFINE_GUEST_HANDLE_STRUCT(xen_add_to_physmap_range);
208
185/* 209/*
186 * Returns the pseudo-physical memory map as it was when the domain 210 * Returns the pseudo-physical memory map as it was when the domain
187 * was started (specified by XENMEM_set_memory_map). 211 * was started (specified by XENMEM_set_memory_map).
@@ -217,4 +241,20 @@ DEFINE_GUEST_HANDLE_STRUCT(xen_memory_map);
217 * during a driver critical region. 241 * during a driver critical region.
218 */ 242 */
219extern spinlock_t xen_reservation_lock; 243extern spinlock_t xen_reservation_lock;
244
245/*
246 * Unmaps the page appearing at a particular GPFN from the specified guest's
247 * pseudophysical address space.
248 * arg == addr of xen_remove_from_physmap_t.
249 */
250#define XENMEM_remove_from_physmap 15
251struct xen_remove_from_physmap {
252 /* Which domain to change the mapping for. */
253 domid_t domid;
254
255 /* GPFN of the current mapping of the page. */
256 xen_pfn_t gpfn;
257};
258DEFINE_GUEST_HANDLE_STRUCT(xen_remove_from_physmap);
259
220#endif /* __XEN_PUBLIC_MEMORY_H__ */ 260#endif /* __XEN_PUBLIC_MEMORY_H__ */
diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h
index 4755b5fac9c7..5e36932ab407 100644
--- a/include/xen/interface/platform.h
+++ b/include/xen/interface/platform.h
@@ -324,6 +324,22 @@ struct xenpf_cpu_ol {
324}; 324};
325DEFINE_GUEST_HANDLE_STRUCT(xenpf_cpu_ol); 325DEFINE_GUEST_HANDLE_STRUCT(xenpf_cpu_ol);
326 326
327/*
328 * CMD 58 and 59 are reserved for cpu hotadd and memory hotadd,
329 * which are already occupied at Xen hypervisor side.
330 */
331#define XENPF_core_parking 60
332struct xenpf_core_parking {
333 /* IN variables */
334#define XEN_CORE_PARKING_SET 1
335#define XEN_CORE_PARKING_GET 2
336 uint32_t type;
337 /* IN variables: set cpu nums expected to be idled */
338 /* OUT variables: get cpu nums actually be idled */
339 uint32_t idle_nums;
340};
341DEFINE_GUEST_HANDLE_STRUCT(xenpf_core_parking);
342
327struct xen_platform_op { 343struct xen_platform_op {
328 uint32_t cmd; 344 uint32_t cmd;
329 uint32_t interface_version; /* XENPF_INTERFACE_VERSION */ 345 uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
@@ -341,6 +357,7 @@ struct xen_platform_op {
341 struct xenpf_set_processor_pminfo set_pminfo; 357 struct xenpf_set_processor_pminfo set_pminfo;
342 struct xenpf_pcpuinfo pcpu_info; 358 struct xenpf_pcpuinfo pcpu_info;
343 struct xenpf_cpu_ol cpu_ol; 359 struct xenpf_cpu_ol cpu_ol;
360 struct xenpf_core_parking core_parking;
344 uint8_t pad[128]; 361 uint8_t pad[128];
345 } u; 362 } u;
346}; 363};
diff --git a/include/xen/xen-ops.h b/include/xen/xen-ops.h
index 6a198e46ab6e..d6fe062cad6b 100644
--- a/include/xen/xen-ops.h
+++ b/include/xen/xen-ops.h
@@ -2,6 +2,7 @@
2#define INCLUDE_XEN_OPS_H 2#define INCLUDE_XEN_OPS_H
3 3
4#include <linux/percpu.h> 4#include <linux/percpu.h>
5#include <asm/xen/interface.h>
5 6
6DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu); 7DECLARE_PER_CPU(struct vcpu_info *, xen_vcpu);
7 8
@@ -26,7 +27,11 @@ void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order);
26struct vm_area_struct; 27struct vm_area_struct;
27int xen_remap_domain_mfn_range(struct vm_area_struct *vma, 28int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
28 unsigned long addr, 29 unsigned long addr,
29 unsigned long mfn, int nr, 30 xen_pfn_t mfn, int nr,
30 pgprot_t prot, unsigned domid); 31 pgprot_t prot, unsigned domid,
32 struct page **pages);
33int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
34 int numpgs, struct page **pages);
31 35
36bool xen_running_on_version_or_later(unsigned int major, unsigned int minor);
32#endif /* INCLUDE_XEN_OPS_H */ 37#endif /* INCLUDE_XEN_OPS_H */