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

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

* 'upstream/for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jeremy/xen: (23 commits)
xen/events: Use PIRQ instead of GSI value when unmapping MSI/MSI-X irqs.
xen: set IO permission early (before early_cpu_init())
xen: re-enable boot-time ballooning
xen/balloon: make sure we only include remaining extra ram
xen/balloon: the balloon_lock is useless
xen: add extra pages to balloon
xen: make evtchn's name less generic
xen/evtchn: the evtchn device is non-seekable
Revert "xen/privcmd: create address space to allow writable mmaps"
xen/events: use locked set|clear_bit() for cpu_evtchn_mask
xen/evtchn: clear secondary CPUs' cpu_evtchn_mask[] after restore
xen/xenfs: update xenfs_mount for new prototype
xen: fix header export to userspace
xen: implement XENMEM_machphys_mapping
xen: set vma flag VM_PFNMAP in the privcmd mmap file_op
xen: xenfs: privcmd: check put_user() return code
xen/evtchn: add missing static
xen/evtchn: Fix name of Xen event-channel device
xen/evtchn: don't do unbind_from_irqhandler under spinlock
xen/evtchn: remove spurious barrier
...

+186 -126
+3 -3
arch/x86/include/asm/xen/interface.h
··· 61 61 #define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) 62 62 #endif 63 63 64 - #ifndef machine_to_phys_mapping 65 - #define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START) 66 - #endif 64 + #define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) 65 + #define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) 66 + #define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>__MACH2PHYS_SHIFT) 67 67 68 68 /* Maximum number of virtual CPUs in multi-processor guests. */ 69 69 #define MAX_VIRT_CPUS 32
+5
arch/x86/include/asm/xen/interface_32.h
··· 32 32 /* And the trap vector is... */ 33 33 #define TRAP_INSTR "int $0x82" 34 34 35 + #define __MACH2PHYS_VIRT_START 0xF5800000 36 + #define __MACH2PHYS_VIRT_END 0xF6800000 37 + 38 + #define __MACH2PHYS_SHIFT 2 39 + 35 40 /* 36 41 * Virtual addresses beyond this are not modifiable by guest OSes. The 37 42 * machine->physical mapping table starts at this address, read-only.
+1 -12
arch/x86/include/asm/xen/interface_64.h
··· 39 39 #define __HYPERVISOR_VIRT_END 0xFFFF880000000000 40 40 #define __MACH2PHYS_VIRT_START 0xFFFF800000000000 41 41 #define __MACH2PHYS_VIRT_END 0xFFFF804000000000 42 - 43 - #ifndef HYPERVISOR_VIRT_START 44 - #define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START) 45 - #define HYPERVISOR_VIRT_END mk_unsigned_long(__HYPERVISOR_VIRT_END) 46 - #endif 47 - 48 - #define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START) 49 - #define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END) 50 - #define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3) 51 - #ifndef machine_to_phys_mapping 52 - #define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START) 53 - #endif 42 + #define __MACH2PHYS_SHIFT 3 54 43 55 44 /* 56 45 * int HYPERVISOR_set_segment_base(unsigned int which, unsigned long base)
+4 -3
arch/x86/include/asm/xen/page.h
··· 5 5 #include <linux/types.h> 6 6 #include <linux/spinlock.h> 7 7 #include <linux/pfn.h> 8 + #include <linux/mm.h> 8 9 9 10 #include <asm/uaccess.h> 10 11 #include <asm/page.h> ··· 36 35 #define MAX_DOMAIN_PAGES \ 37 36 ((unsigned long)((u64)CONFIG_XEN_MAX_DOMAIN_MEMORY * 1024 * 1024 * 1024 / PAGE_SIZE)) 38 37 38 + extern unsigned long *machine_to_phys_mapping; 39 + extern unsigned int machine_to_phys_order; 39 40 40 41 extern unsigned long get_phys_to_machine(unsigned long pfn); 41 42 extern bool set_phys_to_machine(unsigned long pfn, unsigned long mfn); ··· 72 69 if (xen_feature(XENFEAT_auto_translated_physmap)) 73 70 return mfn; 74 71 75 - #if 0 76 72 if (unlikely((mfn >> machine_to_phys_order) != 0)) 77 - return max_mapnr; 78 - #endif 73 + return ~0; 79 74 80 75 pfn = 0; 81 76 /*
+18 -1
arch/x86/xen/enlighten.c
··· 75 75 enum xen_domain_type xen_domain_type = XEN_NATIVE; 76 76 EXPORT_SYMBOL_GPL(xen_domain_type); 77 77 78 + unsigned long *machine_to_phys_mapping = (void *)MACH2PHYS_VIRT_START; 79 + EXPORT_SYMBOL(machine_to_phys_mapping); 80 + unsigned int machine_to_phys_order; 81 + EXPORT_SYMBOL(machine_to_phys_order); 82 + 78 83 struct start_info *xen_start_info; 79 84 EXPORT_SYMBOL_GPL(xen_start_info); 80 85 ··· 1095 1090 /* First C function to be called on Xen boot */ 1096 1091 asmlinkage void __init xen_start_kernel(void) 1097 1092 { 1093 + struct physdev_set_iopl set_iopl; 1094 + int rc; 1098 1095 pgd_t *pgd; 1099 1096 1100 1097 if (!xen_start_info) 1101 1098 return; 1102 1099 1103 1100 xen_domain_type = XEN_PV_DOMAIN; 1101 + 1102 + xen_setup_machphys_mapping(); 1104 1103 1105 1104 /* Install Xen paravirt ops */ 1106 1105 pv_info = xen_info; ··· 1211 1202 #else 1212 1203 pv_info.kernel_rpl = 0; 1213 1204 #endif 1214 - 1215 1205 /* set the limit of our address space */ 1216 1206 xen_reserve_top(); 1207 + 1208 + /* We used to do this in xen_arch_setup, but that is too late on AMD 1209 + * were early_cpu_init (run before ->arch_setup()) calls early_amd_init 1210 + * which pokes 0xcf8 port. 1211 + */ 1212 + set_iopl.iopl = 1; 1213 + rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl); 1214 + if (rc != 0) 1215 + xen_raw_printk("physdev_op failed %d\n", rc); 1217 1216 1218 1217 #ifdef CONFIG_X86_32 1219 1218 /* set up basic CPUID stuff */
+16 -1
arch/x86/xen/mmu.c
··· 2034 2034 set_page_prot(pmd, PAGE_KERNEL_RO); 2035 2035 } 2036 2036 2037 + void __init xen_setup_machphys_mapping(void) 2038 + { 2039 + struct xen_machphys_mapping mapping; 2040 + unsigned long machine_to_phys_nr_ents; 2041 + 2042 + if (HYPERVISOR_memory_op(XENMEM_machphys_mapping, &mapping) == 0) { 2043 + machine_to_phys_mapping = (unsigned long *)mapping.v_start; 2044 + machine_to_phys_nr_ents = mapping.max_mfn + 1; 2045 + } else { 2046 + machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES; 2047 + } 2048 + machine_to_phys_order = fls(machine_to_phys_nr_ents - 1); 2049 + } 2050 + 2037 2051 #ifdef CONFIG_X86_64 2038 2052 static void convert_pfn_mfn(void *v) 2039 2053 { ··· 2641 2627 2642 2628 prot = __pgprot(pgprot_val(prot) | _PAGE_IOMAP); 2643 2629 2644 - vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; 2630 + BUG_ON(!((vma->vm_flags & (VM_PFNMAP | VM_RESERVED | VM_IO)) == 2631 + (VM_PFNMAP | VM_RESERVED | VM_IO))); 2645 2632 2646 2633 rmd.mfn = mfn; 2647 2634 rmd.prot = prot;
+1 -10
arch/x86/xen/setup.c
··· 248 248 else 249 249 extra_pages = 0; 250 250 251 - if (!xen_initial_domain()) 252 - xen_add_extra_mem(extra_pages); 251 + xen_add_extra_mem(extra_pages); 253 252 254 253 return "Xen"; 255 254 } ··· 336 337 337 338 void __init xen_arch_setup(void) 338 339 { 339 - struct physdev_set_iopl set_iopl; 340 - int rc; 341 - 342 340 xen_panic_handler_init(); 343 341 344 342 HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); ··· 351 355 352 356 xen_enable_sysenter(); 353 357 xen_enable_syscall(); 354 - 355 - set_iopl.iopl = 1; 356 - rc = HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl); 357 - if (rc != 0) 358 - printk(KERN_INFO "physdev_op failed %d\n", rc); 359 358 360 359 #ifdef CONFIG_ACPI 361 360 if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
+4 -1
drivers/xen/Makefile
··· 8 8 obj-$(CONFIG_HOTPLUG_CPU) += cpu_hotplug.o 9 9 obj-$(CONFIG_XEN_XENCOMM) += xencomm.o 10 10 obj-$(CONFIG_XEN_BALLOON) += balloon.o 11 - obj-$(CONFIG_XEN_DEV_EVTCHN) += evtchn.o 11 + obj-$(CONFIG_XEN_DEV_EVTCHN) += xen-evtchn.o 12 12 obj-$(CONFIG_XENFS) += xenfs/ 13 13 obj-$(CONFIG_XEN_SYS_HYPERVISOR) += sys-hypervisor.o 14 14 obj-$(CONFIG_XEN_PLATFORM_PCI) += platform-pci.o 15 15 obj-$(CONFIG_SWIOTLB_XEN) += swiotlb-xen.o 16 16 obj-$(CONFIG_XEN_DOM0) += pci.o 17 + 18 + xen-evtchn-y := evtchn.o 19 +
+17 -15
drivers/xen/balloon.c
··· 50 50 #include <asm/pgtable.h> 51 51 #include <asm/uaccess.h> 52 52 #include <asm/tlb.h> 53 + #include <asm/e820.h> 53 54 54 55 #include <asm/xen/hypervisor.h> 55 56 #include <asm/xen/hypercall.h> ··· 120 119 } 121 120 122 121 /* balloon_append: add the given page to the balloon. */ 123 - static void balloon_append(struct page *page) 122 + static void __balloon_append(struct page *page) 124 123 { 125 124 /* Lowmem is re-populated first, so highmem pages go at list tail. */ 126 125 if (PageHighMem(page)) { ··· 131 130 list_add(&page->lru, &ballooned_pages); 132 131 balloon_stats.balloon_low++; 133 132 } 133 + } 134 134 135 + static void balloon_append(struct page *page) 136 + { 137 + __balloon_append(page); 135 138 totalram_pages--; 136 139 } 137 140 ··· 196 191 197 192 static int increase_reservation(unsigned long nr_pages) 198 193 { 199 - unsigned long pfn, i, flags; 194 + unsigned long pfn, i; 200 195 struct page *page; 201 196 long rc; 202 197 struct xen_memory_reservation reservation = { ··· 207 202 208 203 if (nr_pages > ARRAY_SIZE(frame_list)) 209 204 nr_pages = ARRAY_SIZE(frame_list); 210 - 211 - spin_lock_irqsave(&xen_reservation_lock, flags); 212 205 213 206 page = balloon_first_page(); 214 207 for (i = 0; i < nr_pages; i++) { ··· 250 247 balloon_stats.current_pages += rc; 251 248 252 249 out: 253 - spin_unlock_irqrestore(&xen_reservation_lock, flags); 254 - 255 250 return rc < 0 ? rc : rc != nr_pages; 256 251 } 257 252 258 253 static int decrease_reservation(unsigned long nr_pages) 259 254 { 260 - unsigned long pfn, i, flags; 255 + unsigned long pfn, i; 261 256 struct page *page; 262 257 int need_sleep = 0; 263 258 int ret; ··· 293 292 kmap_flush_unused(); 294 293 flush_tlb_all(); 295 294 296 - spin_lock_irqsave(&xen_reservation_lock, flags); 297 - 298 295 /* No more mappings: invalidate P2M and add to balloon. */ 299 296 for (i = 0; i < nr_pages; i++) { 300 297 pfn = mfn_to_pfn(frame_list[i]); ··· 306 307 BUG_ON(ret != nr_pages); 307 308 308 309 balloon_stats.current_pages -= nr_pages; 309 - 310 - spin_unlock_irqrestore(&xen_reservation_lock, flags); 311 310 312 311 return need_sleep; 313 312 } ··· 392 395 393 396 static int __init balloon_init(void) 394 397 { 395 - unsigned long pfn; 398 + unsigned long pfn, extra_pfn_end; 396 399 struct page *page; 397 400 398 401 if (!xen_pv_domain()) ··· 413 416 register_balloon(&balloon_sysdev); 414 417 415 418 /* Initialise the balloon with excess memory space. */ 416 - for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) { 419 + extra_pfn_end = min(e820_end_of_ram_pfn(), 420 + (unsigned long)PFN_DOWN(xen_extra_mem_start + xen_extra_mem_size)); 421 + for (pfn = PFN_UP(xen_extra_mem_start); 422 + pfn < extra_pfn_end; 423 + pfn++) { 417 424 page = pfn_to_page(pfn); 418 - if (!PageReserved(page)) 419 - balloon_append(page); 425 + /* totalram_pages doesn't include the boot-time 426 + balloon extension, so don't subtract from it. */ 427 + __balloon_append(page); 420 428 } 421 429 422 430 target_watch.callback = watch_target;
+8 -5
drivers/xen/events.c
··· 278 278 cpumask_copy(irq_to_desc(irq)->affinity, cpumask_of(cpu)); 279 279 #endif 280 280 281 - __clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq))); 282 - __set_bit(chn, cpu_evtchn_mask(cpu)); 281 + clear_bit(chn, cpu_evtchn_mask(cpu_from_irq(irq))); 282 + set_bit(chn, cpu_evtchn_mask(cpu)); 283 283 284 284 irq_info[irq].cpu = cpu; 285 285 } 286 286 287 287 static void init_evtchn_cpu_bindings(void) 288 288 { 289 + int i; 289 290 #ifdef CONFIG_SMP 290 291 struct irq_desc *desc; 291 - int i; 292 292 293 293 /* By default all event channels notify CPU#0. */ 294 294 for_each_irq_desc(i, desc) { ··· 296 296 } 297 297 #endif 298 298 299 - memset(cpu_evtchn_mask(0), ~0, sizeof(struct cpu_evtchn_s)); 299 + for_each_possible_cpu(i) 300 + memset(cpu_evtchn_mask(i), 301 + (i == 0) ? ~0 : 0, sizeof(struct cpu_evtchn_s)); 302 + 300 303 } 301 304 302 305 static inline void clear_evtchn(int port) ··· 755 752 goto out; 756 753 757 754 if (xen_initial_domain()) { 758 - unmap_irq.pirq = info->u.pirq.gsi; 755 + unmap_irq.pirq = info->u.pirq.pirq; 759 756 unmap_irq.domid = DOMID_SELF; 760 757 rc = HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq); 761 758 if (rc) {
+76 -24
drivers/xen/evtchn.c
··· 69 69 const char *name; 70 70 }; 71 71 72 - /* Who's bound to each port? */ 73 - static struct per_user_data *port_user[NR_EVENT_CHANNELS]; 72 + /* 73 + * Who's bound to each port? This is logically an array of struct 74 + * per_user_data *, but we encode the current enabled-state in bit 0. 75 + */ 76 + static unsigned long *port_user; 74 77 static DEFINE_SPINLOCK(port_user_lock); /* protects port_user[] and ring_prod */ 75 78 76 - irqreturn_t evtchn_interrupt(int irq, void *data) 79 + static inline struct per_user_data *get_port_user(unsigned port) 80 + { 81 + return (struct per_user_data *)(port_user[port] & ~1); 82 + } 83 + 84 + static inline void set_port_user(unsigned port, struct per_user_data *u) 85 + { 86 + port_user[port] = (unsigned long)u; 87 + } 88 + 89 + static inline bool get_port_enabled(unsigned port) 90 + { 91 + return port_user[port] & 1; 92 + } 93 + 94 + static inline void set_port_enabled(unsigned port, bool enabled) 95 + { 96 + if (enabled) 97 + port_user[port] |= 1; 98 + else 99 + port_user[port] &= ~1; 100 + } 101 + 102 + static irqreturn_t evtchn_interrupt(int irq, void *data) 77 103 { 78 104 unsigned int port = (unsigned long)data; 79 105 struct per_user_data *u; 80 106 81 107 spin_lock(&port_user_lock); 82 108 83 - u = port_user[port]; 109 + u = get_port_user(port); 110 + 111 + WARN(!get_port_enabled(port), 112 + "Interrupt for port %d, but apparently not enabled; per-user %p\n", 113 + port, u); 84 114 85 115 disable_irq_nosync(irq); 116 + set_port_enabled(port, false); 86 117 87 118 if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) { 88 119 u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port; ··· 123 92 kill_fasync(&u->evtchn_async_queue, 124 93 SIGIO, POLL_IN); 125 94 } 126 - } else { 95 + } else 127 96 u->ring_overflow = 1; 128 - } 129 97 130 98 spin_unlock(&port_user_lock); 131 99 ··· 228 198 goto out; 229 199 230 200 spin_lock_irq(&port_user_lock); 231 - for (i = 0; i < (count/sizeof(evtchn_port_t)); i++) 232 - if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u)) 233 - enable_irq(irq_from_evtchn(kbuf[i])); 201 + 202 + for (i = 0; i < (count/sizeof(evtchn_port_t)); i++) { 203 + unsigned port = kbuf[i]; 204 + 205 + if (port < NR_EVENT_CHANNELS && 206 + get_port_user(port) == u && 207 + !get_port_enabled(port)) { 208 + set_port_enabled(port, true); 209 + enable_irq(irq_from_evtchn(port)); 210 + } 211 + } 212 + 234 213 spin_unlock_irq(&port_user_lock); 235 214 236 215 rc = count; ··· 261 222 * interrupt handler yet, and our caller has already 262 223 * serialized bind operations.) 263 224 */ 264 - BUG_ON(port_user[port] != NULL); 265 - port_user[port] = u; 225 + BUG_ON(get_port_user(port) != NULL); 226 + set_port_user(port, u); 227 + set_port_enabled(port, true); /* start enabled */ 266 228 267 229 rc = bind_evtchn_to_irqhandler(port, evtchn_interrupt, IRQF_DISABLED, 268 230 u->name, (void *)(unsigned long)port); ··· 279 239 280 240 unbind_from_irqhandler(irq, (void *)(unsigned long)port); 281 241 282 - /* make sure we unbind the irq handler before clearing the port */ 283 - barrier(); 284 - 285 - port_user[port] = NULL; 242 + set_port_user(port, NULL); 286 243 } 287 244 288 245 static long evtchn_ioctl(struct file *file, ··· 370 333 spin_lock_irq(&port_user_lock); 371 334 372 335 rc = -ENOTCONN; 373 - if (port_user[unbind.port] != u) { 336 + if (get_port_user(unbind.port) != u) { 374 337 spin_unlock_irq(&port_user_lock); 375 338 break; 376 339 } 377 340 378 - evtchn_unbind_from_user(u, unbind.port); 341 + disable_irq(irq_from_evtchn(unbind.port)); 379 342 380 343 spin_unlock_irq(&port_user_lock); 344 + 345 + evtchn_unbind_from_user(u, unbind.port); 381 346 382 347 rc = 0; 383 348 break; ··· 394 355 395 356 if (notify.port >= NR_EVENT_CHANNELS) { 396 357 rc = -EINVAL; 397 - } else if (port_user[notify.port] != u) { 358 + } else if (get_port_user(notify.port) != u) { 398 359 rc = -ENOTCONN; 399 360 } else { 400 361 notify_remote_via_evtchn(notify.port); ··· 470 431 471 432 filp->private_data = u; 472 433 473 - return 0; 434 + return nonseekable_open(inode, filp);; 474 435 } 475 436 476 437 static int evtchn_release(struct inode *inode, struct file *filp) ··· 483 444 free_page((unsigned long)u->ring); 484 445 485 446 for (i = 0; i < NR_EVENT_CHANNELS; i++) { 486 - if (port_user[i] != u) 447 + if (get_port_user(i) != u) 487 448 continue; 488 449 489 - evtchn_unbind_from_user(port_user[i], i); 450 + disable_irq(irq_from_evtchn(i)); 490 451 } 491 452 492 453 spin_unlock_irq(&port_user_lock); 454 + 455 + for (i = 0; i < NR_EVENT_CHANNELS; i++) { 456 + if (get_port_user(i) != u) 457 + continue; 458 + 459 + evtchn_unbind_from_user(get_port_user(i), i); 460 + } 493 461 494 462 kfree(u->name); 495 463 kfree(u); ··· 513 467 .fasync = evtchn_fasync, 514 468 .open = evtchn_open, 515 469 .release = evtchn_release, 516 - .llseek = noop_llseek, 470 + .llseek = no_llseek, 517 471 }; 518 472 519 473 static struct miscdevice evtchn_miscdev = { 520 474 .minor = MISC_DYNAMIC_MINOR, 521 - .name = "evtchn", 475 + .name = "xen/evtchn", 522 476 .fops = &evtchn_fops, 523 477 }; 524 478 static int __init evtchn_init(void) ··· 528 482 if (!xen_domain()) 529 483 return -ENODEV; 530 484 485 + port_user = kcalloc(NR_EVENT_CHANNELS, sizeof(*port_user), GFP_KERNEL); 486 + if (port_user == NULL) 487 + return -ENOMEM; 488 + 531 489 spin_lock_init(&port_user_lock); 532 - memset(port_user, 0, sizeof(port_user)); 533 490 534 491 /* Create '/dev/misc/evtchn'. */ 535 492 err = misc_register(&evtchn_miscdev); ··· 548 499 549 500 static void __exit evtchn_cleanup(void) 550 501 { 502 + kfree(port_user); 503 + port_user = NULL; 504 + 551 505 misc_deregister(&evtchn_miscdev); 552 506 } 553 507
+5 -8
drivers/xen/xenfs/privcmd.c
··· 265 265 xen_pfn_t *mfnp = data; 266 266 struct mmap_batch_state *st = state; 267 267 268 - put_user(*mfnp, st->user++); 269 - 270 - return 0; 268 + return put_user(*mfnp, st->user++); 271 269 } 272 270 273 271 static struct vm_operations_struct privcmd_vm_ops; ··· 320 322 up_write(&mm->mmap_sem); 321 323 322 324 if (state.err > 0) { 323 - ret = 0; 324 - 325 325 state.user = m.arr; 326 - traverse_pages(m.num, sizeof(xen_pfn_t), 326 + ret = traverse_pages(m.num, sizeof(xen_pfn_t), 327 327 &pagelist, 328 328 mmap_return_errors, &state); 329 329 } ··· 379 383 if (xen_feature(XENFEAT_auto_translated_physmap)) 380 384 return -ENOSYS; 381 385 382 - /* DONTCOPY is essential for Xen as copy_page_range is broken. */ 383 - vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY; 386 + /* DONTCOPY is essential for Xen because copy_page_range doesn't know 387 + * how to recreate these mappings */ 388 + vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP; 384 389 vma->vm_ops = &privcmd_vm_ops; 385 390 vma->vm_private_data = NULL; 386 391
+7 -39
drivers/xen/xenfs/super.c
··· 12 12 #include <linux/module.h> 13 13 #include <linux/fs.h> 14 14 #include <linux/magic.h> 15 - #include <linux/mm.h> 16 - #include <linux/backing-dev.h> 17 15 18 16 #include <xen/xen.h> 19 17 ··· 22 24 MODULE_DESCRIPTION("Xen filesystem"); 23 25 MODULE_LICENSE("GPL"); 24 26 25 - static int xenfs_set_page_dirty(struct page *page) 26 - { 27 - return !TestSetPageDirty(page); 28 - } 29 - 30 - static const struct address_space_operations xenfs_aops = { 31 - .set_page_dirty = xenfs_set_page_dirty, 32 - }; 33 - 34 - static struct backing_dev_info xenfs_backing_dev_info = { 35 - .ra_pages = 0, /* No readahead */ 36 - .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, 37 - }; 38 - 39 27 static struct inode *xenfs_make_inode(struct super_block *sb, int mode) 40 28 { 41 29 struct inode *ret = new_inode(sb); 42 30 43 31 if (ret) { 44 32 ret->i_mode = mode; 45 - ret->i_mapping->a_ops = &xenfs_aops; 46 - ret->i_mapping->backing_dev_info = &xenfs_backing_dev_info; 47 33 ret->i_uid = ret->i_gid = 0; 48 34 ret->i_blocks = 0; 49 35 ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME; ··· 103 121 return rc; 104 122 } 105 123 106 - static int xenfs_mount(struct file_system_type *fs_type, 107 - int flags, const char *dev_name, 108 - void *data) 124 + static struct dentry *xenfs_mount(struct file_system_type *fs_type, 125 + int flags, const char *dev_name, 126 + void *data) 109 127 { 110 128 return mount_single(fs_type, flags, data, xenfs_fill_super); 111 129 } ··· 119 137 120 138 static int __init xenfs_init(void) 121 139 { 122 - int err; 123 - if (!xen_domain()) { 124 - printk(KERN_INFO "xenfs: not registering filesystem on non-xen platform\n"); 125 - return 0; 126 - } 140 + if (xen_domain()) 141 + return register_filesystem(&xenfs_type); 127 142 128 - err = register_filesystem(&xenfs_type); 129 - if (err) { 130 - printk(KERN_ERR "xenfs: Unable to register filesystem!\n"); 131 - goto out; 132 - } 133 - 134 - err = bdi_init(&xenfs_backing_dev_info); 135 - if (err) 136 - unregister_filesystem(&xenfs_type); 137 - 138 - out: 139 - 140 - return err; 143 + printk(KERN_INFO "XENFS: not registering filesystem on non-xen platform\n"); 144 + return 0; 141 145 } 142 146 143 147 static void __exit xenfs_exit(void)
+13
include/xen/interface/memory.h
··· 141 141 DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mfn_list); 142 142 143 143 /* 144 + * Returns the location in virtual address space of the machine_to_phys 145 + * mapping table. Architectures which do not have a m2p table, or which do not 146 + * map it by default into guest address space, do not implement this command. 147 + * arg == addr of xen_machphys_mapping_t. 148 + */ 149 + #define XENMEM_machphys_mapping 12 150 + struct xen_machphys_mapping { 151 + unsigned long v_start, v_end; /* Start and end virtual addresses. */ 152 + unsigned long max_mfn; /* Maximum MFN that can be looked up. */ 153 + }; 154 + DEFINE_GUEST_HANDLE_STRUCT(xen_machphys_mapping_t); 155 + 156 + /* 144 157 * Sets the GPFN at which a particular page appears in the specified guest's 145 158 * pseudophysical address space. 146 159 * arg == addr of xen_add_to_physmap_t.
+7
include/xen/page.h
··· 1 + #ifndef _XEN_PAGE_H 2 + #define _XEN_PAGE_H 3 + 1 4 #include <asm/xen/page.h> 5 + 6 + extern phys_addr_t xen_extra_mem_start, xen_extra_mem_size; 7 + 8 + #endif /* _XEN_PAGE_H */
+1 -4
include/xen/privcmd.h
··· 34 34 #define __LINUX_PUBLIC_PRIVCMD_H__ 35 35 36 36 #include <linux/types.h> 37 + #include <linux/compiler.h> 37 38 38 39 typedef unsigned long xen_pfn_t; 39 - 40 - #ifndef __user 41 - #define __user 42 - #endif 43 40 44 41 struct privcmd_hypercall { 45 42 __u64 op;