aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-05-08 07:33:33 -0400
committerIngo Molnar <mingo@kernel.org>2015-05-08 07:33:33 -0400
commit7ae383be81781c5e1347f71c3eb0d53ce5188200 (patch)
treed2dfedb78cf4ee2bc9cc460af3be106b08e01050 /arch/x86/xen
parent2a4e90b18c256d52a7f3f77d58114f6d4e4a7f9f (diff)
parent3e0283a53f7d2f2dae7bc4aa7f3104cb5988018f (diff)
Merge branch 'linus' into x86/asm, before applying dependent patch
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/xen')
-rw-r--r--arch/x86/xen/apic.c180
-rw-r--r--arch/x86/xen/enlighten.c117
-rw-r--r--arch/x86/xen/mmu.c221
-rw-r--r--arch/x86/xen/smp.c46
-rw-r--r--arch/x86/xen/suspend.c10
-rw-r--r--arch/x86/xen/trace.c50
-rw-r--r--arch/x86/xen/xen-head.S63
7 files changed, 338 insertions, 349 deletions
diff --git a/arch/x86/xen/apic.c b/arch/x86/xen/apic.c
index 7005ced5d1ad..70e060ad879a 100644
--- a/arch/x86/xen/apic.c
+++ b/arch/x86/xen/apic.c
@@ -7,6 +7,7 @@
7#include <xen/xen.h> 7#include <xen/xen.h>
8#include <xen/interface/physdev.h> 8#include <xen/interface/physdev.h>
9#include "xen-ops.h" 9#include "xen-ops.h"
10#include "smp.h"
10 11
11static unsigned int xen_io_apic_read(unsigned apic, unsigned reg) 12static unsigned int xen_io_apic_read(unsigned apic, unsigned reg)
12{ 13{
@@ -28,7 +29,186 @@ static unsigned int xen_io_apic_read(unsigned apic, unsigned reg)
28 return 0xfd; 29 return 0xfd;
29} 30}
30 31
32static unsigned long xen_set_apic_id(unsigned int x)
33{
34 WARN_ON(1);
35 return x;
36}
37
38static unsigned int xen_get_apic_id(unsigned long x)
39{
40 return ((x)>>24) & 0xFFu;
41}
42
43static u32 xen_apic_read(u32 reg)
44{
45 struct xen_platform_op op = {
46 .cmd = XENPF_get_cpuinfo,
47 .interface_version = XENPF_INTERFACE_VERSION,
48 .u.pcpu_info.xen_cpuid = 0,
49 };
50 int ret = 0;
51
52 /* Shouldn't need this as APIC is turned off for PV, and we only
53 * get called on the bootup processor. But just in case. */
54 if (!xen_initial_domain() || smp_processor_id())
55 return 0;
56
57 if (reg == APIC_LVR)
58 return 0x10;
59#ifdef CONFIG_X86_32
60 if (reg == APIC_LDR)
61 return SET_APIC_LOGICAL_ID(1UL << smp_processor_id());
62#endif
63 if (reg != APIC_ID)
64 return 0;
65
66 ret = HYPERVISOR_dom0_op(&op);
67 if (ret)
68 return 0;
69
70 return op.u.pcpu_info.apic_id << 24;
71}
72
73static void xen_apic_write(u32 reg, u32 val)
74{
75 /* Warn to see if there's any stray references */
76 WARN(1,"register: %x, value: %x\n", reg, val);
77}
78
79static u64 xen_apic_icr_read(void)
80{
81 return 0;
82}
83
84static void xen_apic_icr_write(u32 low, u32 id)
85{
86 /* Warn to see if there's any stray references */
87 WARN_ON(1);
88}
89
90static u32 xen_safe_apic_wait_icr_idle(void)
91{
92 return 0;
93}
94
95static int xen_apic_probe_pv(void)
96{
97 if (xen_pv_domain())
98 return 1;
99
100 return 0;
101}
102
103static int xen_madt_oem_check(char *oem_id, char *oem_table_id)
104{
105 return xen_pv_domain();
106}
107
108static int xen_id_always_valid(int apicid)
109{
110 return 1;
111}
112
113static int xen_id_always_registered(void)
114{
115 return 1;
116}
117
118static int xen_phys_pkg_id(int initial_apic_id, int index_msb)
119{
120 return initial_apic_id >> index_msb;
121}
122
123#ifdef CONFIG_X86_32
124static int xen_x86_32_early_logical_apicid(int cpu)
125{
126 /* Match with APIC_LDR read. Otherwise setup_local_APIC complains. */
127 return 1 << cpu;
128}
129#endif
130
131static void xen_noop(void)
132{
133}
134
135static void xen_silent_inquire(int apicid)
136{
137}
138
139static struct apic xen_pv_apic = {
140 .name = "Xen PV",
141 .probe = xen_apic_probe_pv,
142 .acpi_madt_oem_check = xen_madt_oem_check,
143 .apic_id_valid = xen_id_always_valid,
144 .apic_id_registered = xen_id_always_registered,
145
146 /* .irq_delivery_mode - used in native_compose_msi_msg only */
147 /* .irq_dest_mode - used in native_compose_msi_msg only */
148
149 .target_cpus = default_target_cpus,
150 .disable_esr = 0,
151 /* .dest_logical - default_send_IPI_ use it but we use our own. */
152 .check_apicid_used = default_check_apicid_used, /* Used on 32-bit */
153
154 .vector_allocation_domain = flat_vector_allocation_domain,
155 .init_apic_ldr = xen_noop, /* setup_local_APIC calls it */
156
157 .ioapic_phys_id_map = default_ioapic_phys_id_map, /* Used on 32-bit */
158 .setup_apic_routing = NULL,
159 .cpu_present_to_apicid = default_cpu_present_to_apicid,
160 .apicid_to_cpu_present = physid_set_mask_of_physid, /* Used on 32-bit */
161 .check_phys_apicid_present = default_check_phys_apicid_present, /* smp_sanity_check needs it */
162 .phys_pkg_id = xen_phys_pkg_id, /* detect_ht */
163
164 .get_apic_id = xen_get_apic_id,
165 .set_apic_id = xen_set_apic_id, /* Can be NULL on 32-bit. */
166 .apic_id_mask = 0xFF << 24, /* Used by verify_local_APIC. Match with what xen_get_apic_id does. */
167
168 .cpu_mask_to_apicid_and = flat_cpu_mask_to_apicid_and,
169
170#ifdef CONFIG_SMP
171 .send_IPI_mask = xen_send_IPI_mask,
172 .send_IPI_mask_allbutself = xen_send_IPI_mask_allbutself,
173 .send_IPI_allbutself = xen_send_IPI_allbutself,
174 .send_IPI_all = xen_send_IPI_all,
175 .send_IPI_self = xen_send_IPI_self,
176#endif
177 /* .wait_for_init_deassert- used by AP bootup - smp_callin which we don't use */
178 .inquire_remote_apic = xen_silent_inquire,
179
180 .read = xen_apic_read,
181 .write = xen_apic_write,
182 .eoi_write = xen_apic_write,
183
184 .icr_read = xen_apic_icr_read,
185 .icr_write = xen_apic_icr_write,
186 .wait_icr_idle = xen_noop,
187 .safe_wait_icr_idle = xen_safe_apic_wait_icr_idle,
188
189#ifdef CONFIG_X86_32
190 /* generic_processor_info and setup_local_APIC. */
191 .x86_32_early_logical_apicid = xen_x86_32_early_logical_apicid,
192#endif
193};
194
195static void __init xen_apic_check(void)
196{
197 if (apic == &xen_pv_apic)
198 return;
199
200 pr_info("Switched APIC routing from %s to %s.\n", apic->name,
201 xen_pv_apic.name);
202 apic = &xen_pv_apic;
203}
31void __init xen_init_apic(void) 204void __init xen_init_apic(void)
32{ 205{
33 x86_io_apic_ops.read = xen_io_apic_read; 206 x86_io_apic_ops.read = xen_io_apic_read;
207 /* On PV guests the APIC CPUID bit is disabled so none of the
208 * routines end up executing. */
209 if (!xen_initial_domain())
210 apic = &xen_pv_apic;
211
212 x86_platform.apic_post_init = xen_apic_check;
34} 213}
214apic_driver(xen_pv_apic);
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 3797b6b31f95..fe969ac1c65e 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -928,92 +928,6 @@ static void xen_io_delay(void)
928{ 928{
929} 929}
930 930
931#ifdef CONFIG_X86_LOCAL_APIC
932static unsigned long xen_set_apic_id(unsigned int x)
933{
934 WARN_ON(1);
935 return x;
936}
937static unsigned int xen_get_apic_id(unsigned long x)
938{
939 return ((x)>>24) & 0xFFu;
940}
941static u32 xen_apic_read(u32 reg)
942{
943 struct xen_platform_op op = {
944 .cmd = XENPF_get_cpuinfo,
945 .interface_version = XENPF_INTERFACE_VERSION,
946 .u.pcpu_info.xen_cpuid = 0,
947 };
948 int ret = 0;
949
950 /* Shouldn't need this as APIC is turned off for PV, and we only
951 * get called on the bootup processor. But just in case. */
952 if (!xen_initial_domain() || smp_processor_id())
953 return 0;
954
955 if (reg == APIC_LVR)
956 return 0x10;
957
958 if (reg != APIC_ID)
959 return 0;
960
961 ret = HYPERVISOR_dom0_op(&op);
962 if (ret)
963 return 0;
964
965 return op.u.pcpu_info.apic_id << 24;
966}
967
968static void xen_apic_write(u32 reg, u32 val)
969{
970 /* Warn to see if there's any stray references */
971 WARN_ON(1);
972}
973
974static u64 xen_apic_icr_read(void)
975{
976 return 0;
977}
978
979static void xen_apic_icr_write(u32 low, u32 id)
980{
981 /* Warn to see if there's any stray references */
982 WARN_ON(1);
983}
984
985static void xen_apic_wait_icr_idle(void)
986{
987 return;
988}
989
990static u32 xen_safe_apic_wait_icr_idle(void)
991{
992 return 0;
993}
994
995static void set_xen_basic_apic_ops(void)
996{
997 apic->read = xen_apic_read;
998 apic->write = xen_apic_write;
999 apic->icr_read = xen_apic_icr_read;
1000 apic->icr_write = xen_apic_icr_write;
1001 apic->wait_icr_idle = xen_apic_wait_icr_idle;
1002 apic->safe_wait_icr_idle = xen_safe_apic_wait_icr_idle;
1003 apic->set_apic_id = xen_set_apic_id;
1004 apic->get_apic_id = xen_get_apic_id;
1005
1006#ifdef CONFIG_SMP
1007 apic->send_IPI_allbutself = xen_send_IPI_allbutself;
1008 apic->send_IPI_mask_allbutself = xen_send_IPI_mask_allbutself;
1009 apic->send_IPI_mask = xen_send_IPI_mask;
1010 apic->send_IPI_all = xen_send_IPI_all;
1011 apic->send_IPI_self = xen_send_IPI_self;
1012#endif
1013}
1014
1015#endif
1016
1017static void xen_clts(void) 931static void xen_clts(void)
1018{ 932{
1019 struct multicall_space mcs; 933 struct multicall_space mcs;
@@ -1620,7 +1534,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
1620 /* 1534 /*
1621 * set up the basic apic ops. 1535 * set up the basic apic ops.
1622 */ 1536 */
1623 set_xen_basic_apic_ops(); 1537 xen_init_apic();
1624#endif 1538#endif
1625 1539
1626 if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) { 1540 if (xen_feature(XENFEAT_mmu_pt_update_preserve_ad)) {
@@ -1733,8 +1647,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
1733 if (HYPERVISOR_dom0_op(&op) == 0) 1647 if (HYPERVISOR_dom0_op(&op) == 0)
1734 boot_params.kbd_status = op.u.firmware_info.u.kbd_shift_flags; 1648 boot_params.kbd_status = op.u.firmware_info.u.kbd_shift_flags;
1735 1649
1736 xen_init_apic();
1737
1738 /* Make sure ACS will be enabled */ 1650 /* Make sure ACS will be enabled */
1739 pci_request_acs(); 1651 pci_request_acs();
1740 1652
@@ -1849,6 +1761,9 @@ static struct notifier_block xen_hvm_cpu_notifier = {
1849 1761
1850static void __init xen_hvm_guest_init(void) 1762static void __init xen_hvm_guest_init(void)
1851{ 1763{
1764 if (xen_pv_domain())
1765 return;
1766
1852 init_hvm_pv_info(); 1767 init_hvm_pv_info();
1853 1768
1854 xen_hvm_init_shared_info(); 1769 xen_hvm_init_shared_info();
@@ -1864,6 +1779,7 @@ static void __init xen_hvm_guest_init(void)
1864 xen_hvm_init_time_ops(); 1779 xen_hvm_init_time_ops();
1865 xen_hvm_init_mmu_ops(); 1780 xen_hvm_init_mmu_ops();
1866} 1781}
1782#endif
1867 1783
1868static bool xen_nopv = false; 1784static bool xen_nopv = false;
1869static __init int xen_parse_nopv(char *arg) 1785static __init int xen_parse_nopv(char *arg)
@@ -1873,14 +1789,11 @@ static __init int xen_parse_nopv(char *arg)
1873} 1789}
1874early_param("xen_nopv", xen_parse_nopv); 1790early_param("xen_nopv", xen_parse_nopv);
1875 1791
1876static uint32_t __init xen_hvm_platform(void) 1792static uint32_t __init xen_platform(void)
1877{ 1793{
1878 if (xen_nopv) 1794 if (xen_nopv)
1879 return 0; 1795 return 0;
1880 1796
1881 if (xen_pv_domain())
1882 return 0;
1883
1884 return xen_cpuid_base(); 1797 return xen_cpuid_base();
1885} 1798}
1886 1799
@@ -1898,11 +1811,19 @@ bool xen_hvm_need_lapic(void)
1898} 1811}
1899EXPORT_SYMBOL_GPL(xen_hvm_need_lapic); 1812EXPORT_SYMBOL_GPL(xen_hvm_need_lapic);
1900 1813
1901const struct hypervisor_x86 x86_hyper_xen_hvm __refconst = { 1814static void xen_set_cpu_features(struct cpuinfo_x86 *c)
1902 .name = "Xen HVM", 1815{
1903 .detect = xen_hvm_platform, 1816 if (xen_pv_domain())
1817 clear_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
1818}
1819
1820const struct hypervisor_x86 x86_hyper_xen = {
1821 .name = "Xen",
1822 .detect = xen_platform,
1823#ifdef CONFIG_XEN_PVHVM
1904 .init_platform = xen_hvm_guest_init, 1824 .init_platform = xen_hvm_guest_init,
1825#endif
1905 .x2apic_available = xen_x2apic_para_available, 1826 .x2apic_available = xen_x2apic_para_available,
1827 .set_cpu_features = xen_set_cpu_features,
1906}; 1828};
1907EXPORT_SYMBOL(x86_hyper_xen_hvm); 1829EXPORT_SYMBOL(x86_hyper_xen);
1908#endif
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index adca9e2b6553..dd151b2045b0 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -502,7 +502,7 @@ __visible pmd_t xen_make_pmd(pmdval_t pmd)
502} 502}
503PV_CALLEE_SAVE_REGS_THUNK(xen_make_pmd); 503PV_CALLEE_SAVE_REGS_THUNK(xen_make_pmd);
504 504
505#if PAGETABLE_LEVELS == 4 505#if CONFIG_PGTABLE_LEVELS == 4
506__visible pudval_t xen_pud_val(pud_t pud) 506__visible pudval_t xen_pud_val(pud_t pud)
507{ 507{
508 return pte_mfn_to_pfn(pud.pud); 508 return pte_mfn_to_pfn(pud.pud);
@@ -589,7 +589,7 @@ static void xen_set_pgd(pgd_t *ptr, pgd_t val)
589 589
590 xen_mc_issue(PARAVIRT_LAZY_MMU); 590 xen_mc_issue(PARAVIRT_LAZY_MMU);
591} 591}
592#endif /* PAGETABLE_LEVELS == 4 */ 592#endif /* CONFIG_PGTABLE_LEVELS == 4 */
593 593
594/* 594/*
595 * (Yet another) pagetable walker. This one is intended for pinning a 595 * (Yet another) pagetable walker. This one is intended for pinning a
@@ -1628,7 +1628,7 @@ static void xen_release_pmd(unsigned long pfn)
1628 xen_release_ptpage(pfn, PT_PMD); 1628 xen_release_ptpage(pfn, PT_PMD);
1629} 1629}
1630 1630
1631#if PAGETABLE_LEVELS == 4 1631#if CONFIG_PGTABLE_LEVELS == 4
1632static void xen_alloc_pud(struct mm_struct *mm, unsigned long pfn) 1632static void xen_alloc_pud(struct mm_struct *mm, unsigned long pfn)
1633{ 1633{
1634 xen_alloc_ptpage(mm, pfn, PT_PUD); 1634 xen_alloc_ptpage(mm, pfn, PT_PUD);
@@ -2046,7 +2046,7 @@ static void __init xen_post_allocator_init(void)
2046 pv_mmu_ops.set_pte = xen_set_pte; 2046 pv_mmu_ops.set_pte = xen_set_pte;
2047 pv_mmu_ops.set_pmd = xen_set_pmd; 2047 pv_mmu_ops.set_pmd = xen_set_pmd;
2048 pv_mmu_ops.set_pud = xen_set_pud; 2048 pv_mmu_ops.set_pud = xen_set_pud;
2049#if PAGETABLE_LEVELS == 4 2049#if CONFIG_PGTABLE_LEVELS == 4
2050 pv_mmu_ops.set_pgd = xen_set_pgd; 2050 pv_mmu_ops.set_pgd = xen_set_pgd;
2051#endif 2051#endif
2052 2052
@@ -2056,7 +2056,7 @@ static void __init xen_post_allocator_init(void)
2056 pv_mmu_ops.alloc_pmd = xen_alloc_pmd; 2056 pv_mmu_ops.alloc_pmd = xen_alloc_pmd;
2057 pv_mmu_ops.release_pte = xen_release_pte; 2057 pv_mmu_ops.release_pte = xen_release_pte;
2058 pv_mmu_ops.release_pmd = xen_release_pmd; 2058 pv_mmu_ops.release_pmd = xen_release_pmd;
2059#if PAGETABLE_LEVELS == 4 2059#if CONFIG_PGTABLE_LEVELS == 4
2060 pv_mmu_ops.alloc_pud = xen_alloc_pud; 2060 pv_mmu_ops.alloc_pud = xen_alloc_pud;
2061 pv_mmu_ops.release_pud = xen_release_pud; 2061 pv_mmu_ops.release_pud = xen_release_pud;
2062#endif 2062#endif
@@ -2122,14 +2122,14 @@ static const struct pv_mmu_ops xen_mmu_ops __initconst = {
2122 .make_pmd = PV_CALLEE_SAVE(xen_make_pmd), 2122 .make_pmd = PV_CALLEE_SAVE(xen_make_pmd),
2123 .pmd_val = PV_CALLEE_SAVE(xen_pmd_val), 2123 .pmd_val = PV_CALLEE_SAVE(xen_pmd_val),
2124 2124
2125#if PAGETABLE_LEVELS == 4 2125#if CONFIG_PGTABLE_LEVELS == 4
2126 .pud_val = PV_CALLEE_SAVE(xen_pud_val), 2126 .pud_val = PV_CALLEE_SAVE(xen_pud_val),
2127 .make_pud = PV_CALLEE_SAVE(xen_make_pud), 2127 .make_pud = PV_CALLEE_SAVE(xen_make_pud),
2128 .set_pgd = xen_set_pgd_hyper, 2128 .set_pgd = xen_set_pgd_hyper,
2129 2129
2130 .alloc_pud = xen_alloc_pmd_init, 2130 .alloc_pud = xen_alloc_pmd_init,
2131 .release_pud = xen_release_pmd_init, 2131 .release_pud = xen_release_pmd_init,
2132#endif /* PAGETABLE_LEVELS == 4 */ 2132#endif /* CONFIG_PGTABLE_LEVELS == 4 */
2133 2133
2134 .activate_mm = xen_activate_mm, 2134 .activate_mm = xen_activate_mm,
2135 .dup_mmap = xen_dup_mmap, 2135 .dup_mmap = xen_dup_mmap,
@@ -2436,99 +2436,11 @@ void __init xen_hvm_init_mmu_ops(void)
2436} 2436}
2437#endif 2437#endif
2438 2438
2439#ifdef CONFIG_XEN_PVH
2440/*
2441 * Map foreign gfn (fgfn), to local pfn (lpfn). This for the user
2442 * space creating new guest on pvh dom0 and needing to map domU pages.
2443 */
2444static int xlate_add_to_p2m(unsigned long lpfn, unsigned long fgfn,
2445 unsigned int domid)
2446{
2447 int rc, err = 0;
2448 xen_pfn_t gpfn = lpfn;
2449 xen_ulong_t idx = fgfn;
2450
2451 struct xen_add_to_physmap_range xatp = {
2452 .domid = DOMID_SELF,
2453 .foreign_domid = domid,
2454 .size = 1,
2455 .space = XENMAPSPACE_gmfn_foreign,
2456 };
2457 set_xen_guest_handle(xatp.idxs, &idx);
2458 set_xen_guest_handle(xatp.gpfns, &gpfn);
2459 set_xen_guest_handle(xatp.errs, &err);
2460
2461 rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap_range, &xatp);
2462 if (rc < 0)
2463 return rc;
2464 return err;
2465}
2466
2467static int xlate_remove_from_p2m(unsigned long spfn, int count)
2468{
2469 struct xen_remove_from_physmap xrp;
2470 int i, rc;
2471
2472 for (i = 0; i < count; i++) {
2473 xrp.domid = DOMID_SELF;
2474 xrp.gpfn = spfn+i;
2475 rc = HYPERVISOR_memory_op(XENMEM_remove_from_physmap, &xrp);
2476 if (rc)
2477 break;
2478 }
2479 return rc;
2480}
2481
2482struct xlate_remap_data {
2483 unsigned long fgfn; /* foreign domain's gfn */
2484 pgprot_t prot;
2485 domid_t domid;
2486 int index;
2487 struct page **pages;
2488};
2489
2490static int xlate_map_pte_fn(pte_t *ptep, pgtable_t token, unsigned long addr,
2491 void *data)
2492{
2493 int rc;
2494 struct xlate_remap_data *remap = data;
2495 unsigned long pfn = page_to_pfn(remap->pages[remap->index++]);
2496 pte_t pteval = pte_mkspecial(pfn_pte(pfn, remap->prot));
2497
2498 rc = xlate_add_to_p2m(pfn, remap->fgfn, remap->domid);
2499 if (rc)
2500 return rc;
2501 native_set_pte(ptep, pteval);
2502
2503 return 0;
2504}
2505
2506static int xlate_remap_gfn_range(struct vm_area_struct *vma,
2507 unsigned long addr, unsigned long mfn,
2508 int nr, pgprot_t prot, unsigned domid,
2509 struct page **pages)
2510{
2511 int err;
2512 struct xlate_remap_data pvhdata;
2513
2514 BUG_ON(!pages);
2515
2516 pvhdata.fgfn = mfn;
2517 pvhdata.prot = prot;
2518 pvhdata.domid = domid;
2519 pvhdata.index = 0;
2520 pvhdata.pages = pages;
2521 err = apply_to_page_range(vma->vm_mm, addr, nr << PAGE_SHIFT,
2522 xlate_map_pte_fn, &pvhdata);
2523 flush_tlb_all();
2524 return err;
2525}
2526#endif
2527
2528#define REMAP_BATCH_SIZE 16 2439#define REMAP_BATCH_SIZE 16
2529 2440
2530struct remap_data { 2441struct remap_data {
2531 unsigned long mfn; 2442 xen_pfn_t *mfn;
2443 bool contiguous;
2532 pgprot_t prot; 2444 pgprot_t prot;
2533 struct mmu_update *mmu_update; 2445 struct mmu_update *mmu_update;
2534}; 2446};
@@ -2537,7 +2449,14 @@ static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token,
2537 unsigned long addr, void *data) 2449 unsigned long addr, void *data)
2538{ 2450{
2539 struct remap_data *rmd = data; 2451 struct remap_data *rmd = data;
2540 pte_t pte = pte_mkspecial(mfn_pte(rmd->mfn++, rmd->prot)); 2452 pte_t pte = pte_mkspecial(mfn_pte(*rmd->mfn, rmd->prot));
2453
2454 /* If we have a contigious range, just update the mfn itself,
2455 else update pointer to be "next mfn". */
2456 if (rmd->contiguous)
2457 (*rmd->mfn)++;
2458 else
2459 rmd->mfn++;
2541 2460
2542 rmd->mmu_update->ptr = virt_to_machine(ptep).maddr; 2461 rmd->mmu_update->ptr = virt_to_machine(ptep).maddr;
2543 rmd->mmu_update->val = pte_val_ma(pte); 2462 rmd->mmu_update->val = pte_val_ma(pte);
@@ -2546,26 +2465,26 @@ static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token,
2546 return 0; 2465 return 0;
2547} 2466}
2548 2467
2549int xen_remap_domain_mfn_range(struct vm_area_struct *vma, 2468static int do_remap_mfn(struct vm_area_struct *vma,
2550 unsigned long addr, 2469 unsigned long addr,
2551 xen_pfn_t mfn, int nr, 2470 xen_pfn_t *mfn, int nr,
2552 pgprot_t prot, unsigned domid, 2471 int *err_ptr, pgprot_t prot,
2553 struct page **pages) 2472 unsigned domid,
2554 2473 struct page **pages)
2555{ 2474{
2475 int err = 0;
2556 struct remap_data rmd; 2476 struct remap_data rmd;
2557 struct mmu_update mmu_update[REMAP_BATCH_SIZE]; 2477 struct mmu_update mmu_update[REMAP_BATCH_SIZE];
2558 int batch;
2559 unsigned long range; 2478 unsigned long range;
2560 int err = 0; 2479 int mapped = 0;
2561 2480
2562 BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_IO)) == (VM_PFNMAP | VM_IO))); 2481 BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_IO)) == (VM_PFNMAP | VM_IO)));
2563 2482
2564 if (xen_feature(XENFEAT_auto_translated_physmap)) { 2483 if (xen_feature(XENFEAT_auto_translated_physmap)) {
2565#ifdef CONFIG_XEN_PVH 2484#ifdef CONFIG_XEN_PVH
2566 /* We need to update the local page tables and the xen HAP */ 2485 /* We need to update the local page tables and the xen HAP */
2567 return xlate_remap_gfn_range(vma, addr, mfn, nr, prot, 2486 return xen_xlate_remap_gfn_array(vma, addr, mfn, nr, err_ptr,
2568 domid, pages); 2487 prot, domid, pages);
2569#else 2488#else
2570 return -EINVAL; 2489 return -EINVAL;
2571#endif 2490#endif
@@ -2573,9 +2492,15 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
2573 2492
2574 rmd.mfn = mfn; 2493 rmd.mfn = mfn;
2575 rmd.prot = prot; 2494 rmd.prot = prot;
2495 /* We use the err_ptr to indicate if there we are doing a contigious
2496 * mapping or a discontigious mapping. */
2497 rmd.contiguous = !err_ptr;
2576 2498
2577 while (nr) { 2499 while (nr) {
2578 batch = min(REMAP_BATCH_SIZE, nr); 2500 int index = 0;
2501 int done = 0;
2502 int batch = min(REMAP_BATCH_SIZE, nr);
2503 int batch_left = batch;
2579 range = (unsigned long)batch << PAGE_SHIFT; 2504 range = (unsigned long)batch << PAGE_SHIFT;
2580 2505
2581 rmd.mmu_update = mmu_update; 2506 rmd.mmu_update = mmu_update;
@@ -2584,23 +2509,72 @@ int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
2584 if (err) 2509 if (err)
2585 goto out; 2510 goto out;
2586 2511
2587 err = HYPERVISOR_mmu_update(mmu_update, batch, NULL, domid); 2512 /* We record the error for each page that gives an error, but
2588 if (err < 0) 2513 * continue mapping until the whole set is done */
2589 goto out; 2514 do {
2515 int i;
2516
2517 err = HYPERVISOR_mmu_update(&mmu_update[index],
2518 batch_left, &done, domid);
2519
2520 /*
2521 * @err_ptr may be the same buffer as @mfn, so
2522 * only clear it after each chunk of @mfn is
2523 * used.
2524 */
2525 if (err_ptr) {
2526 for (i = index; i < index + done; i++)
2527 err_ptr[i] = 0;
2528 }
2529 if (err < 0) {
2530 if (!err_ptr)
2531 goto out;
2532 err_ptr[i] = err;
2533 done++; /* Skip failed frame. */
2534 } else
2535 mapped += done;
2536 batch_left -= done;
2537 index += done;
2538 } while (batch_left);
2590 2539
2591 nr -= batch; 2540 nr -= batch;
2592 addr += range; 2541 addr += range;
2542 if (err_ptr)
2543 err_ptr += batch;
2593 } 2544 }
2594
2595 err = 0;
2596out: 2545out:
2597 2546
2598 xen_flush_tlb_all(); 2547 xen_flush_tlb_all();
2599 2548
2600 return err; 2549 return err < 0 ? err : mapped;
2550}
2551
2552int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
2553 unsigned long addr,
2554 xen_pfn_t mfn, int nr,
2555 pgprot_t prot, unsigned domid,
2556 struct page **pages)
2557{
2558 return do_remap_mfn(vma, addr, &mfn, nr, NULL, prot, domid, pages);
2601} 2559}
2602EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range); 2560EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
2603 2561
2562int xen_remap_domain_mfn_array(struct vm_area_struct *vma,
2563 unsigned long addr,
2564 xen_pfn_t *mfn, int nr,
2565 int *err_ptr, pgprot_t prot,
2566 unsigned domid, struct page **pages)
2567{
2568 /* We BUG_ON because it's a programmer error to pass a NULL err_ptr,
2569 * and the consequences later is quite hard to detect what the actual
2570 * cause of "wrong memory was mapped in".
2571 */
2572 BUG_ON(err_ptr == NULL);
2573 return do_remap_mfn(vma, addr, mfn, nr, err_ptr, prot, domid, pages);
2574}
2575EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_array);
2576
2577
2604/* Returns: 0 success */ 2578/* Returns: 0 success */
2605int xen_unmap_domain_mfn_range(struct vm_area_struct *vma, 2579int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
2606 int numpgs, struct page **pages) 2580 int numpgs, struct page **pages)
@@ -2609,22 +2583,7 @@ int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
2609 return 0; 2583 return 0;
2610 2584
2611#ifdef CONFIG_XEN_PVH 2585#ifdef CONFIG_XEN_PVH
2612 while (numpgs--) { 2586 return xen_xlate_unmap_gfn_range(vma, numpgs, pages);
2613 /*
2614 * The mmu has already cleaned up the process mmu
2615 * resources at this point (lookup_address will return
2616 * NULL).
2617 */
2618 unsigned long pfn = page_to_pfn(pages[numpgs]);
2619
2620 xlate_remove_from_p2m(pfn, 1);
2621 }
2622 /*
2623 * We don't need to flush tlbs because as part of
2624 * xlate_remove_from_p2m, the hypervisor will do tlb flushes
2625 * after removing the p2m entries from the EPT/NPT
2626 */
2627 return 0;
2628#else 2587#else
2629 return -EINVAL; 2588 return -EINVAL;
2630#endif 2589#endif
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 7413ee3706d0..86484384492e 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -90,14 +90,10 @@ static void cpu_bringup(void)
90 90
91 set_cpu_online(cpu, true); 91 set_cpu_online(cpu, true);
92 92
93 this_cpu_write(cpu_state, CPU_ONLINE); 93 cpu_set_state_online(cpu); /* Implies full memory barrier. */
94
95 wmb();
96 94
97 /* We can take interrupts now: we're officially "up". */ 95 /* We can take interrupts now: we're officially "up". */
98 local_irq_enable(); 96 local_irq_enable();
99
100 wmb(); /* make sure everything is out */
101} 97}
102 98
103/* 99/*
@@ -451,7 +447,13 @@ static int xen_cpu_up(unsigned int cpu, struct task_struct *idle)
451 xen_setup_timer(cpu); 447 xen_setup_timer(cpu);
452 xen_init_lock_cpu(cpu); 448 xen_init_lock_cpu(cpu);
453 449
454 per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; 450 /*
451 * PV VCPUs are always successfully taken down (see 'while' loop
452 * in xen_cpu_die()), so -EBUSY is an error.
453 */
454 rc = cpu_check_up_prepare(cpu);
455 if (rc)
456 return rc;
455 457
456 /* make sure interrupts start blocked */ 458 /* make sure interrupts start blocked */
457 per_cpu(xen_vcpu, cpu)->evtchn_upcall_mask = 1; 459 per_cpu(xen_vcpu, cpu)->evtchn_upcall_mask = 1;
@@ -467,10 +469,8 @@ static int xen_cpu_up(unsigned int cpu, struct task_struct *idle)
467 rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); 469 rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
468 BUG_ON(rc); 470 BUG_ON(rc);
469 471
470 while(per_cpu(cpu_state, cpu) != CPU_ONLINE) { 472 while (cpu_report_state(cpu) != CPU_ONLINE)
471 HYPERVISOR_sched_op(SCHEDOP_yield, NULL); 473 HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
472 barrier();
473 }
474 474
475 return 0; 475 return 0;
476} 476}
@@ -499,11 +499,11 @@ static void xen_cpu_die(unsigned int cpu)
499 schedule_timeout(HZ/10); 499 schedule_timeout(HZ/10);
500 } 500 }
501 501
502 cpu_die_common(cpu); 502 if (common_cpu_die(cpu) == 0) {
503 503 xen_smp_intr_free(cpu);
504 xen_smp_intr_free(cpu); 504 xen_uninit_lock_cpu(cpu);
505 xen_uninit_lock_cpu(cpu); 505 xen_teardown_timer(cpu);
506 xen_teardown_timer(cpu); 506 }
507} 507}
508 508
509static void xen_play_dead(void) /* used only with HOTPLUG_CPU */ 509static void xen_play_dead(void) /* used only with HOTPLUG_CPU */
@@ -735,6 +735,16 @@ static void __init xen_hvm_smp_prepare_cpus(unsigned int max_cpus)
735static int xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle) 735static int xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle)
736{ 736{
737 int rc; 737 int rc;
738
739 /*
740 * This can happen if CPU was offlined earlier and
741 * offlining timed out in common_cpu_die().
742 */
743 if (cpu_report_state(cpu) == CPU_DEAD_FROZEN) {
744 xen_smp_intr_free(cpu);
745 xen_uninit_lock_cpu(cpu);
746 }
747
738 /* 748 /*
739 * xen_smp_intr_init() needs to run before native_cpu_up() 749 * xen_smp_intr_init() needs to run before native_cpu_up()
740 * so that IPI vectors are set up on the booting CPU before 750 * so that IPI vectors are set up on the booting CPU before
@@ -756,12 +766,6 @@ static int xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle)
756 return rc; 766 return rc;
757} 767}
758 768
759static void xen_hvm_cpu_die(unsigned int cpu)
760{
761 xen_cpu_die(cpu);
762 native_cpu_die(cpu);
763}
764
765void __init xen_hvm_smp_init(void) 769void __init xen_hvm_smp_init(void)
766{ 770{
767 if (!xen_have_vector_callback) 771 if (!xen_have_vector_callback)
@@ -769,7 +773,7 @@ void __init xen_hvm_smp_init(void)
769 smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus; 773 smp_ops.smp_prepare_cpus = xen_hvm_smp_prepare_cpus;
770 smp_ops.smp_send_reschedule = xen_smp_send_reschedule; 774 smp_ops.smp_send_reschedule = xen_smp_send_reschedule;
771 smp_ops.cpu_up = xen_hvm_cpu_up; 775 smp_ops.cpu_up = xen_hvm_cpu_up;
772 smp_ops.cpu_die = xen_hvm_cpu_die; 776 smp_ops.cpu_die = xen_cpu_die;
773 smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi; 777 smp_ops.send_call_func_ipi = xen_smp_send_call_function_ipi;
774 smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi; 778 smp_ops.send_call_func_single_ipi = xen_smp_send_call_function_single_ipi;
775 smp_ops.smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu; 779 smp_ops.smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu;
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
index d9497698645a..53b4c0811f4f 100644
--- a/arch/x86/xen/suspend.c
+++ b/arch/x86/xen/suspend.c
@@ -88,7 +88,17 @@ static void xen_vcpu_notify_restore(void *data)
88 tick_resume_local(); 88 tick_resume_local();
89} 89}
90 90
91static void xen_vcpu_notify_suspend(void *data)
92{
93 tick_suspend_local();
94}
95
91void xen_arch_resume(void) 96void xen_arch_resume(void)
92{ 97{
93 on_each_cpu(xen_vcpu_notify_restore, NULL, 1); 98 on_each_cpu(xen_vcpu_notify_restore, NULL, 1);
94} 99}
100
101void xen_arch_suspend(void)
102{
103 on_each_cpu(xen_vcpu_notify_suspend, NULL, 1);
104}
diff --git a/arch/x86/xen/trace.c b/arch/x86/xen/trace.c
index 520022d1a181..a702ec2f5931 100644
--- a/arch/x86/xen/trace.c
+++ b/arch/x86/xen/trace.c
@@ -1,54 +1,12 @@
1#include <linux/ftrace.h> 1#include <linux/ftrace.h>
2#include <xen/interface/xen.h> 2#include <xen/interface/xen.h>
3#include <xen/interface/xen-mca.h>
3 4
4#define N(x) [__HYPERVISOR_##x] = "("#x")" 5#define HYPERCALL(x) [__HYPERVISOR_##x] = "("#x")",
5static const char *xen_hypercall_names[] = { 6static const char *xen_hypercall_names[] = {
6 N(set_trap_table), 7#include <asm/xen-hypercalls.h>
7 N(mmu_update),
8 N(set_gdt),
9 N(stack_switch),
10 N(set_callbacks),
11 N(fpu_taskswitch),
12 N(sched_op_compat),
13 N(dom0_op),
14 N(set_debugreg),
15 N(get_debugreg),
16 N(update_descriptor),
17 N(memory_op),
18 N(multicall),
19 N(update_va_mapping),
20 N(set_timer_op),
21 N(event_channel_op_compat),
22 N(xen_version),
23 N(console_io),
24 N(physdev_op_compat),
25 N(grant_table_op),
26 N(vm_assist),
27 N(update_va_mapping_otherdomain),
28 N(iret),
29 N(vcpu_op),
30 N(set_segment_base),
31 N(mmuext_op),
32 N(acm_op),
33 N(nmi_op),
34 N(sched_op),
35 N(callback_op),
36 N(xenoprof_op),
37 N(event_channel_op),
38 N(physdev_op),
39 N(hvm_op),
40
41/* Architecture-specific hypercall definitions. */
42 N(arch_0),
43 N(arch_1),
44 N(arch_2),
45 N(arch_3),
46 N(arch_4),
47 N(arch_5),
48 N(arch_6),
49 N(arch_7),
50}; 8};
51#undef N 9#undef HYPERCALL
52 10
53static const char *xen_hypercall_name(unsigned op) 11static const char *xen_hypercall_name(unsigned op)
54{ 12{
diff --git a/arch/x86/xen/xen-head.S b/arch/x86/xen/xen-head.S
index 674b222544b7..8afdfccf6086 100644
--- a/arch/x86/xen/xen-head.S
+++ b/arch/x86/xen/xen-head.S
@@ -12,6 +12,8 @@
12 12
13#include <xen/interface/elfnote.h> 13#include <xen/interface/elfnote.h>
14#include <xen/interface/features.h> 14#include <xen/interface/features.h>
15#include <xen/interface/xen.h>
16#include <xen/interface/xen-mca.h>
15#include <asm/xen/interface.h> 17#include <asm/xen/interface.h>
16 18
17#ifdef CONFIG_XEN_PVH 19#ifdef CONFIG_XEN_PVH
@@ -85,59 +87,14 @@ ENTRY(xen_pvh_early_cpu_init)
85.pushsection .text 87.pushsection .text
86 .balign PAGE_SIZE 88 .balign PAGE_SIZE
87ENTRY(hypercall_page) 89ENTRY(hypercall_page)
88#define NEXT_HYPERCALL(x) \ 90 .skip PAGE_SIZE
89 ENTRY(xen_hypercall_##x) \ 91
90 .skip 32 92#define HYPERCALL(n) \
91 93 .equ xen_hypercall_##n, hypercall_page + __HYPERVISOR_##n * 32; \
92NEXT_HYPERCALL(set_trap_table) 94 .type xen_hypercall_##n, @function; .size xen_hypercall_##n, 32
93NEXT_HYPERCALL(mmu_update) 95#include <asm/xen-hypercalls.h>
94NEXT_HYPERCALL(set_gdt) 96#undef HYPERCALL
95NEXT_HYPERCALL(stack_switch) 97
96NEXT_HYPERCALL(set_callbacks)
97NEXT_HYPERCALL(fpu_taskswitch)
98NEXT_HYPERCALL(sched_op_compat)
99NEXT_HYPERCALL(platform_op)
100NEXT_HYPERCALL(set_debugreg)
101NEXT_HYPERCALL(get_debugreg)
102NEXT_HYPERCALL(update_descriptor)
103NEXT_HYPERCALL(ni)
104NEXT_HYPERCALL(memory_op)
105NEXT_HYPERCALL(multicall)
106NEXT_HYPERCALL(update_va_mapping)
107NEXT_HYPERCALL(set_timer_op)
108NEXT_HYPERCALL(event_channel_op_compat)
109NEXT_HYPERCALL(xen_version)
110NEXT_HYPERCALL(console_io)
111NEXT_HYPERCALL(physdev_op_compat)
112NEXT_HYPERCALL(grant_table_op)
113NEXT_HYPERCALL(vm_assist)
114NEXT_HYPERCALL(update_va_mapping_otherdomain)
115NEXT_HYPERCALL(iret)
116NEXT_HYPERCALL(vcpu_op)
117NEXT_HYPERCALL(set_segment_base)
118NEXT_HYPERCALL(mmuext_op)
119NEXT_HYPERCALL(xsm_op)
120NEXT_HYPERCALL(nmi_op)
121NEXT_HYPERCALL(sched_op)
122NEXT_HYPERCALL(callback_op)
123NEXT_HYPERCALL(xenoprof_op)
124NEXT_HYPERCALL(event_channel_op)
125NEXT_HYPERCALL(physdev_op)
126NEXT_HYPERCALL(hvm_op)
127NEXT_HYPERCALL(sysctl)
128NEXT_HYPERCALL(domctl)
129NEXT_HYPERCALL(kexec_op)
130NEXT_HYPERCALL(tmem_op) /* 38 */
131ENTRY(xen_hypercall_rsvr)
132 .skip 320
133NEXT_HYPERCALL(mca) /* 48 */
134NEXT_HYPERCALL(arch_1)
135NEXT_HYPERCALL(arch_2)
136NEXT_HYPERCALL(arch_3)
137NEXT_HYPERCALL(arch_4)
138NEXT_HYPERCALL(arch_5)
139NEXT_HYPERCALL(arch_6)
140 .balign PAGE_SIZE
141.popsection 98.popsection
142 99
143 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux") 100 ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux")