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

Configure Feed

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

Merge branch 'for-rc1/xen/core' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen

* 'for-rc1/xen/core' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen:
xen: add FIX_TEXT_POKE to fixmap
xen: honour VCPU availability on boot
xen: clean up gate trap/interrupt constants
xen: set _PAGE_NX in __supported_pte_mask before pagetable construction
xen: resume interrupts before system devices.
xen/mmu: weaken flush_tlb_other test
xen/mmu: some early pagetable cleanups
Xen: Add virt_to_pfn helper function
x86-64: remove PGE from must-have feature list
xen: mask XSAVE from cpuid
NULL noise: arch/x86/xen/smp.c
xen: remove xen_load_gdt debug
xen: make xen_load_gdt simpler
xen: clean up xen_load_gdt
xen: split construction of p2m mfn tables from registration
xen: separate p2m allocation from setting
xen: disable preempt for leave_lazy_mmu

+198 -76
+1 -1
arch/x86/include/asm/required-features.h
··· 50 50 #ifdef CONFIG_X86_64 51 51 #define NEED_PSE 0 52 52 #define NEED_MSR (1<<(X86_FEATURE_MSR & 31)) 53 - #define NEED_PGE (1<<(X86_FEATURE_PGE & 31)) 53 + #define NEED_PGE 0 54 54 #define NEED_FXSR (1<<(X86_FEATURE_FXSR & 31)) 55 55 #define NEED_XMM (1<<(X86_FEATURE_XMM & 31)) 56 56 #define NEED_XMM2 (1<<(X86_FEATURE_XMM2 & 31))
+2 -1
arch/x86/include/asm/xen/page.h
··· 124 124 125 125 /* VIRT <-> MACHINE conversion */ 126 126 #define virt_to_machine(v) (phys_to_machine(XPADDR(__pa(v)))) 127 - #define virt_to_mfn(v) (pfn_to_mfn(PFN_DOWN(__pa(v)))) 127 + #define virt_to_pfn(v) (PFN_DOWN(__pa(v))) 128 + #define virt_to_mfn(v) (pfn_to_mfn(virt_to_pfn(v))) 128 129 #define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT)) 129 130 130 131 static inline unsigned long pte_mfn(pte_t pte)
+69 -20
arch/x86/xen/enlighten.c
··· 42 42 #include <asm/xen/hypervisor.h> 43 43 #include <asm/fixmap.h> 44 44 #include <asm/processor.h> 45 + #include <asm/proto.h> 45 46 #include <asm/msr-index.h> 46 47 #include <asm/setup.h> 47 48 #include <asm/desc.h> ··· 169 168 xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); 170 169 } 171 170 171 + static __read_mostly unsigned int cpuid_leaf1_edx_mask = ~0; 172 + static __read_mostly unsigned int cpuid_leaf1_ecx_mask = ~0; 173 + 172 174 static void xen_cpuid(unsigned int *ax, unsigned int *bx, 173 175 unsigned int *cx, unsigned int *dx) 174 176 { 177 + unsigned maskecx = ~0; 175 178 unsigned maskedx = ~0; 176 179 177 180 /* 178 181 * Mask out inconvenient features, to try and disable as many 179 182 * unsupported kernel subsystems as possible. 180 183 */ 181 - if (*ax == 1) 182 - maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */ 183 - (1 << X86_FEATURE_ACPI) | /* disable ACPI */ 184 - (1 << X86_FEATURE_MCE) | /* disable MCE */ 185 - (1 << X86_FEATURE_MCA) | /* disable MCA */ 186 - (1 << X86_FEATURE_ACC)); /* thermal monitoring */ 184 + if (*ax == 1) { 185 + maskecx = cpuid_leaf1_ecx_mask; 186 + maskedx = cpuid_leaf1_edx_mask; 187 + } 187 188 188 189 asm(XEN_EMULATE_PREFIX "cpuid" 189 190 : "=a" (*ax), ··· 193 190 "=c" (*cx), 194 191 "=d" (*dx) 195 192 : "0" (*ax), "2" (*cx)); 193 + 194 + *cx &= maskecx; 196 195 *dx &= maskedx; 196 + } 197 + 198 + static __init void xen_init_cpuid_mask(void) 199 + { 200 + unsigned int ax, bx, cx, dx; 201 + 202 + cpuid_leaf1_edx_mask = 203 + ~((1 << X86_FEATURE_MCE) | /* disable MCE */ 204 + (1 << X86_FEATURE_MCA) | /* disable MCA */ 205 + (1 << X86_FEATURE_ACC)); /* thermal monitoring */ 206 + 207 + if (!xen_initial_domain()) 208 + cpuid_leaf1_edx_mask &= 209 + ~((1 << X86_FEATURE_APIC) | /* disable local APIC */ 210 + (1 << X86_FEATURE_ACPI)); /* disable ACPI */ 211 + 212 + ax = 1; 213 + xen_cpuid(&ax, &bx, &cx, &dx); 214 + 215 + /* cpuid claims we support xsave; try enabling it to see what happens */ 216 + if (cx & (1 << (X86_FEATURE_XSAVE % 32))) { 217 + unsigned long cr4; 218 + 219 + set_in_cr4(X86_CR4_OSXSAVE); 220 + 221 + cr4 = read_cr4(); 222 + 223 + if ((cr4 & X86_CR4_OSXSAVE) == 0) 224 + cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_XSAVE % 32)); 225 + 226 + clear_in_cr4(X86_CR4_OSXSAVE); 227 + } 197 228 } 198 229 199 230 static void xen_set_debugreg(int reg, unsigned long val) ··· 321 284 322 285 static void xen_load_gdt(const struct desc_ptr *dtr) 323 286 { 324 - unsigned long *frames; 325 287 unsigned long va = dtr->address; 326 288 unsigned int size = dtr->size + 1; 327 289 unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; 290 + unsigned long frames[pages]; 328 291 int f; 329 - struct multicall_space mcs; 330 292 331 293 /* A GDT can be up to 64k in size, which corresponds to 8192 332 294 8-byte entries, or 16 4k pages.. */ ··· 333 297 BUG_ON(size > 65536); 334 298 BUG_ON(va & ~PAGE_MASK); 335 299 336 - mcs = xen_mc_entry(sizeof(*frames) * pages); 337 - frames = mcs.args; 338 - 339 300 for (f = 0; va < dtr->address + size; va += PAGE_SIZE, f++) { 340 - frames[f] = arbitrary_virt_to_mfn((void *)va); 301 + int level; 302 + pte_t *ptep = lookup_address(va, &level); 303 + unsigned long pfn, mfn; 304 + void *virt; 305 + 306 + BUG_ON(ptep == NULL); 307 + 308 + pfn = pte_pfn(*ptep); 309 + mfn = pfn_to_mfn(pfn); 310 + virt = __va(PFN_PHYS(pfn)); 311 + 312 + frames[f] = mfn; 341 313 342 314 make_lowmem_page_readonly((void *)va); 343 - make_lowmem_page_readonly(mfn_to_virt(frames[f])); 315 + make_lowmem_page_readonly(virt); 344 316 } 345 317 346 - MULTI_set_gdt(mcs.mc, frames, size / sizeof(struct desc_struct)); 347 - 348 - xen_mc_issue(PARAVIRT_LAZY_CPU); 318 + if (HYPERVISOR_set_gdt(frames, size / sizeof(struct desc_struct))) 319 + BUG(); 349 320 } 350 321 351 322 static void load_TLS_descriptor(struct thread_struct *t, ··· 428 385 static int cvt_gate_to_trap(int vector, const gate_desc *val, 429 386 struct trap_info *info) 430 387 { 431 - if (val->type != 0xf && val->type != 0xe) 388 + if (val->type != GATE_TRAP && val->type != GATE_INTERRUPT) 432 389 return 0; 433 390 434 391 info->vector = vector; ··· 436 393 info->cs = gate_segment(*val); 437 394 info->flags = val->dpl; 438 395 /* interrupt gates clear IF */ 439 - if (val->type == 0xe) 440 - info->flags |= 4; 396 + if (val->type == GATE_INTERRUPT) 397 + info->flags |= 1 << 2; 441 398 442 399 return 1; 443 400 } ··· 915 872 .emergency_restart = xen_emergency_restart, 916 873 }; 917 874 918 - 919 875 /* First C function to be called on Xen boot */ 920 876 asmlinkage void __init xen_start_kernel(void) 921 877 { ··· 938 896 pv_mmu_ops = xen_mmu_ops; 939 897 940 898 xen_init_irq_ops(); 899 + 900 + xen_init_cpuid_mask(); 941 901 942 902 #ifdef CONFIG_X86_LOCAL_APIC 943 903 /* ··· 981 937 __supported_pte_mask &= ~_PAGE_GLOBAL; 982 938 if (!xen_initial_domain()) 983 939 __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD); 940 + 941 + #ifdef CONFIG_X86_64 942 + /* Work out if we support NX */ 943 + check_efer(); 944 + #endif 984 945 985 946 /* Don't do the full vcpu_info placement stuff until we have a 986 947 possible map and a non-dummy shared_info. */
+88 -38
arch/x86/xen/mmu.c
··· 184 184 } 185 185 186 186 /* Build the parallel p2m_top_mfn structures */ 187 - void xen_setup_mfn_list_list(void) 187 + static void __init xen_build_mfn_list_list(void) 188 188 { 189 189 unsigned pfn, idx; 190 190 ··· 198 198 unsigned topidx = idx * P2M_ENTRIES_PER_PAGE; 199 199 p2m_top_mfn_list[idx] = virt_to_mfn(&p2m_top_mfn[topidx]); 200 200 } 201 + } 201 202 203 + void xen_setup_mfn_list_list(void) 204 + { 202 205 BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info); 203 206 204 207 HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = ··· 221 218 222 219 p2m_top[topidx] = &mfn_list[pfn]; 223 220 } 221 + 222 + xen_build_mfn_list_list(); 224 223 } 225 224 226 225 unsigned long get_phys_to_machine(unsigned long pfn) ··· 238 233 } 239 234 EXPORT_SYMBOL_GPL(get_phys_to_machine); 240 235 241 - static void alloc_p2m(unsigned long **pp, unsigned long *mfnp) 236 + /* install a new p2m_top page */ 237 + bool install_p2mtop_page(unsigned long pfn, unsigned long *p) 242 238 { 243 - unsigned long *p; 239 + unsigned topidx = p2m_top_index(pfn); 240 + unsigned long **pfnp, *mfnp; 244 241 unsigned i; 245 242 246 - p = (void *)__get_free_page(GFP_KERNEL | __GFP_NOFAIL); 247 - BUG_ON(p == NULL); 243 + pfnp = &p2m_top[topidx]; 244 + mfnp = &p2m_top_mfn[topidx]; 248 245 249 246 for (i = 0; i < P2M_ENTRIES_PER_PAGE; i++) 250 247 p[i] = INVALID_P2M_ENTRY; 251 248 252 - if (cmpxchg(pp, p2m_missing, p) != p2m_missing) 253 - free_page((unsigned long)p); 254 - else 249 + if (cmpxchg(pfnp, p2m_missing, p) == p2m_missing) { 255 250 *mfnp = virt_to_mfn(p); 251 + return true; 252 + } 253 + 254 + return false; 255 + } 256 + 257 + static void alloc_p2m(unsigned long pfn) 258 + { 259 + unsigned long *p; 260 + 261 + p = (void *)__get_free_page(GFP_KERNEL | __GFP_NOFAIL); 262 + BUG_ON(p == NULL); 263 + 264 + if (!install_p2mtop_page(pfn, p)) 265 + free_page((unsigned long)p); 266 + } 267 + 268 + /* Try to install p2m mapping; fail if intermediate bits missing */ 269 + bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn) 270 + { 271 + unsigned topidx, idx; 272 + 273 + if (unlikely(pfn >= MAX_DOMAIN_PAGES)) { 274 + BUG_ON(mfn != INVALID_P2M_ENTRY); 275 + return true; 276 + } 277 + 278 + topidx = p2m_top_index(pfn); 279 + if (p2m_top[topidx] == p2m_missing) { 280 + if (mfn == INVALID_P2M_ENTRY) 281 + return true; 282 + return false; 283 + } 284 + 285 + idx = p2m_index(pfn); 286 + p2m_top[topidx][idx] = mfn; 287 + 288 + return true; 256 289 } 257 290 258 291 void set_phys_to_machine(unsigned long pfn, unsigned long mfn) 259 292 { 260 - unsigned topidx, idx; 261 - 262 293 if (unlikely(xen_feature(XENFEAT_auto_translated_physmap))) { 263 294 BUG_ON(pfn != mfn && mfn != INVALID_P2M_ENTRY); 264 295 return; 265 296 } 266 297 267 - if (unlikely(pfn >= MAX_DOMAIN_PAGES)) { 268 - BUG_ON(mfn != INVALID_P2M_ENTRY); 269 - return; 270 - } 298 + if (unlikely(!__set_phys_to_machine(pfn, mfn))) { 299 + alloc_p2m(pfn); 271 300 272 - topidx = p2m_top_index(pfn); 273 - if (p2m_top[topidx] == p2m_missing) { 274 - /* no need to allocate a page to store an invalid entry */ 275 - if (mfn == INVALID_P2M_ENTRY) 276 - return; 277 - alloc_p2m(&p2m_top[topidx], &p2m_top_mfn[topidx]); 301 + if (!__set_phys_to_machine(pfn, mfn)) 302 + BUG(); 278 303 } 279 - 280 - idx = p2m_index(pfn); 281 - p2m_top[topidx][idx] = mfn; 282 304 } 283 305 284 306 unsigned long arbitrary_virt_to_mfn(void *vaddr) ··· 1019 987 return 0; 1020 988 } 1021 989 1022 - void __init xen_mark_init_mm_pinned(void) 990 + static void __init xen_mark_init_mm_pinned(void) 1023 991 { 1024 992 xen_pgd_walk(&init_mm, xen_mark_pinned, FIXADDR_TOP); 1025 993 } ··· 1302 1270 } *args; 1303 1271 struct multicall_space mcs; 1304 1272 1305 - BUG_ON(cpumask_empty(cpus)); 1306 - BUG_ON(!mm); 1273 + if (cpumask_empty(cpus)) 1274 + return; /* nothing to do */ 1307 1275 1308 1276 mcs = xen_mc_entry(sizeof(*args)); 1309 1277 args = mcs.args; ··· 1470 1438 } 1471 1439 #endif 1472 1440 1441 + static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) 1442 + { 1443 + struct mmuext_op op; 1444 + op.cmd = cmd; 1445 + op.arg1.mfn = pfn_to_mfn(pfn); 1446 + if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) 1447 + BUG(); 1448 + } 1449 + 1473 1450 /* Early in boot, while setting up the initial pagetable, assume 1474 1451 everything is pinned. */ 1475 1452 static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn) 1453 + { 1454 + #ifdef CONFIG_FLATMEM 1455 + BUG_ON(mem_map); /* should only be used early */ 1456 + #endif 1457 + make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); 1458 + pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); 1459 + } 1460 + 1461 + /* Used for pmd and pud */ 1462 + static __init void xen_alloc_pmd_init(struct mm_struct *mm, unsigned long pfn) 1476 1463 { 1477 1464 #ifdef CONFIG_FLATMEM 1478 1465 BUG_ON(mem_map); /* should only be used early */ ··· 1501 1450 1502 1451 /* Early release_pte assumes that all pts are pinned, since there's 1503 1452 only init_mm and anything attached to that is pinned. */ 1504 - static void xen_release_pte_init(unsigned long pfn) 1453 + static __init void xen_release_pte_init(unsigned long pfn) 1505 1454 { 1455 + pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); 1506 1456 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); 1507 1457 } 1508 1458 1509 - static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn) 1459 + static __init void xen_release_pmd_init(unsigned long pfn) 1510 1460 { 1511 - struct mmuext_op op; 1512 - op.cmd = cmd; 1513 - op.arg1.mfn = pfn_to_mfn(pfn); 1514 - if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) 1515 - BUG(); 1461 + make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); 1516 1462 } 1517 1463 1518 1464 /* This needs to make sure the new pte page is pinned iff its being ··· 1821 1773 #ifdef CONFIG_X86_LOCAL_APIC 1822 1774 case FIX_APIC_BASE: /* maps dummy local APIC */ 1823 1775 #endif 1776 + case FIX_TEXT_POKE0: 1777 + case FIX_TEXT_POKE1: 1778 + /* All local page mappings */ 1824 1779 pte = pfn_pte(phys, prot); 1825 1780 break; 1826 1781 ··· 1870 1819 xen_mark_init_mm_pinned(); 1871 1820 } 1872 1821 1873 - 1874 1822 const struct pv_mmu_ops xen_mmu_ops __initdata = { 1875 1823 .pagetable_setup_start = xen_pagetable_setup_start, 1876 1824 .pagetable_setup_done = xen_pagetable_setup_done, ··· 1893 1843 1894 1844 .alloc_pte = xen_alloc_pte_init, 1895 1845 .release_pte = xen_release_pte_init, 1896 - .alloc_pmd = xen_alloc_pte_init, 1846 + .alloc_pmd = xen_alloc_pmd_init, 1897 1847 .alloc_pmd_clone = paravirt_nop, 1898 - .release_pmd = xen_release_pte_init, 1848 + .release_pmd = xen_release_pmd_init, 1899 1849 1900 1850 #ifdef CONFIG_HIGHPTE 1901 1851 .kmap_atomic_pte = xen_kmap_atomic_pte, ··· 1933 1883 .make_pud = PV_CALLEE_SAVE(xen_make_pud), 1934 1884 .set_pgd = xen_set_pgd_hyper, 1935 1885 1936 - .alloc_pud = xen_alloc_pte_init, 1937 - .release_pud = xen_release_pte_init, 1886 + .alloc_pud = xen_alloc_pmd_init, 1887 + .release_pud = xen_release_pmd_init, 1938 1888 #endif /* PAGETABLE_LEVELS == 4 */ 1939 1889 1940 1890 .activate_mm = xen_activate_mm,
+3
arch/x86/xen/mmu.h
··· 11 11 }; 12 12 13 13 14 + bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn); 15 + bool install_p2mtop_page(unsigned long pfn, unsigned long *p); 16 + 14 17 void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags); 15 18 16 19
+2 -2
arch/x86/xen/smp.c
··· 317 317 BUG_ON(rc); 318 318 319 319 while(per_cpu(cpu_state, cpu) != CPU_ONLINE) { 320 - HYPERVISOR_sched_op(SCHEDOP_yield, 0); 320 + HYPERVISOR_sched_op(SCHEDOP_yield, NULL); 321 321 barrier(); 322 322 } 323 323 ··· 422 422 /* Make sure other vcpus get a chance to run if they need to. */ 423 423 for_each_cpu(cpu, mask) { 424 424 if (xen_vcpu_stolen(cpu)) { 425 - HYPERVISOR_sched_op(SCHEDOP_yield, 0); 425 + HYPERVISOR_sched_op(SCHEDOP_yield, NULL); 426 426 break; 427 427 } 428 428 }
-2
arch/x86/xen/xen-ops.h
··· 57 57 58 58 bool xen_vcpu_stolen(int vcpu); 59 59 60 - void xen_mark_init_mm_pinned(void); 61 - 62 60 void xen_setup_vcpu_info_placement(void); 63 61 64 62 #ifdef CONFIG_SMP
+30 -10
drivers/xen/cpu_hotplug.c
··· 21 21 set_cpu_present(cpu, false); 22 22 } 23 23 24 - static void vcpu_hotplug(unsigned int cpu) 24 + static int vcpu_online(unsigned int cpu) 25 25 { 26 26 int err; 27 27 char dir[32], state[32]; 28 - 29 - if (!cpu_possible(cpu)) 30 - return; 31 28 32 29 sprintf(dir, "cpu/%u", cpu); 33 30 err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state); 34 31 if (err != 1) { 35 32 printk(KERN_ERR "XENBUS: Unable to read cpu state\n"); 36 - return; 33 + return err; 37 34 } 38 35 39 - if (strcmp(state, "online") == 0) { 36 + if (strcmp(state, "online") == 0) 37 + return 1; 38 + else if (strcmp(state, "offline") == 0) 39 + return 0; 40 + 41 + printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n", state, cpu); 42 + return -EINVAL; 43 + } 44 + static void vcpu_hotplug(unsigned int cpu) 45 + { 46 + if (!cpu_possible(cpu)) 47 + return; 48 + 49 + switch (vcpu_online(cpu)) { 50 + case 1: 40 51 enable_hotplug_cpu(cpu); 41 - } else if (strcmp(state, "offline") == 0) { 52 + break; 53 + case 0: 42 54 (void)cpu_down(cpu); 43 55 disable_hotplug_cpu(cpu); 44 - } else { 45 - printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n", 46 - state, cpu); 56 + break; 57 + default: 58 + break; 47 59 } 48 60 } 49 61 ··· 76 64 static int setup_cpu_watcher(struct notifier_block *notifier, 77 65 unsigned long event, void *data) 78 66 { 67 + int cpu; 79 68 static struct xenbus_watch cpu_watch = { 80 69 .node = "cpu", 81 70 .callback = handle_vcpu_hotplug_event}; 82 71 83 72 (void)register_xenbus_watch(&cpu_watch); 73 + 74 + for_each_possible_cpu(cpu) { 75 + if (vcpu_online(cpu) == 0) { 76 + (void)cpu_down(cpu); 77 + cpu_clear(cpu, cpu_present_map); 78 + } 79 + } 84 80 85 81 return NOTIFY_DONE; 86 82 }
+3 -2
drivers/xen/manage.c
··· 62 62 gnttab_resume(); 63 63 xen_mm_unpin_all(); 64 64 65 - sysdev_resume(); 66 - 67 65 if (!*cancelled) { 68 66 xen_irq_resume(); 69 67 xen_console_resume(); 70 68 xen_timer_resume(); 71 69 } 70 + 71 + sysdev_resume(); 72 + device_power_up(PMSG_RESUME); 72 73 73 74 return 0; 74 75 }