aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-18 10:18:07 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-18 10:18:07 -0500
commitb6844523839779030430ff28f036f83e2a3f43e6 (patch)
tree0af97f08911fab7e1351646172b1805c287ea300
parent15bd1cfb3055d866614cdaf38e43201936264e50 (diff)
parent99cb2ddcc617f43917e94a4147aa3ccdb2bcd77e (diff)
Merge branch 'stable/for-linus-fixes-3.2' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
* 'stable/for-linus-fixes-3.2' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: xen-gntalloc: signedness bug in add_grefs() xen-gntalloc: integer overflow in gntalloc_ioctl_alloc() xen-gntdev: integer overflow in gntdev_alloc_map() xen:pvhvm: enable PVHVM VCPU placement when using more than 32 CPUs. xen/balloon: Avoid OOM when requesting highmem xen: Remove hanging references to CONFIG_XEN_PLATFORM_PCI xen: map foreign pages for shared rings by updating the PTEs directly
-rw-r--r--arch/x86/xen/enlighten.c3
-rw-r--r--arch/x86/xen/grant-table.c2
-rw-r--r--drivers/xen/balloon.c4
-rw-r--r--drivers/xen/gntalloc.c4
-rw-r--r--drivers/xen/gntdev.c10
-rw-r--r--drivers/xen/xenbus/xenbus_client.c11
-rw-r--r--include/linux/vmalloc.h2
-rw-r--r--include/xen/platform_pci.h6
-rw-r--r--mm/nommu.c2
-rw-r--r--mm/vmalloc.c27
10 files changed, 36 insertions, 35 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index da8afd576a6b..1f928659c338 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1356,7 +1356,7 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
1356 int cpu = (long)hcpu; 1356 int cpu = (long)hcpu;
1357 switch (action) { 1357 switch (action) {
1358 case CPU_UP_PREPARE: 1358 case CPU_UP_PREPARE:
1359 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; 1359 xen_vcpu_setup(cpu);
1360 if (xen_have_vector_callback) 1360 if (xen_have_vector_callback)
1361 xen_init_lock_cpu(cpu); 1361 xen_init_lock_cpu(cpu);
1362 break; 1362 break;
@@ -1386,7 +1386,6 @@ static void __init xen_hvm_guest_init(void)
1386 xen_hvm_smp_init(); 1386 xen_hvm_smp_init();
1387 register_cpu_notifier(&xen_hvm_cpu_notifier); 1387 register_cpu_notifier(&xen_hvm_cpu_notifier);
1388 xen_unplug_emulated_devices(); 1388 xen_unplug_emulated_devices();
1389 have_vcpu_info_placement = 0;
1390 x86_init.irqs.intr_init = xen_init_IRQ; 1389 x86_init.irqs.intr_init = xen_init_IRQ;
1391 xen_hvm_init_time_ops(); 1390 xen_hvm_init_time_ops();
1392 xen_hvm_init_mmu_ops(); 1391 xen_hvm_init_mmu_ops();
diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c
index 6bbfd7ac5e81..5a40d24ba331 100644
--- a/arch/x86/xen/grant-table.c
+++ b/arch/x86/xen/grant-table.c
@@ -71,7 +71,7 @@ int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,
71 71
72 if (shared == NULL) { 72 if (shared == NULL) {
73 struct vm_struct *area = 73 struct vm_struct *area =
74 alloc_vm_area(PAGE_SIZE * max_nr_gframes); 74 alloc_vm_area(PAGE_SIZE * max_nr_gframes, NULL);
75 BUG_ON(area == NULL); 75 BUG_ON(area == NULL);
76 shared = area->addr; 76 shared = area->addr;
77 *__shared = shared; 77 *__shared = shared;
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index a767884a6c7a..31ab82fda38a 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -501,7 +501,7 @@ EXPORT_SYMBOL_GPL(balloon_set_new_target);
501 * alloc_xenballooned_pages - get pages that have been ballooned out 501 * alloc_xenballooned_pages - get pages that have been ballooned out
502 * @nr_pages: Number of pages to get 502 * @nr_pages: Number of pages to get
503 * @pages: pages returned 503 * @pages: pages returned
504 * @highmem: highmem or lowmem pages 504 * @highmem: allow highmem pages
505 * @return 0 on success, error otherwise 505 * @return 0 on success, error otherwise
506 */ 506 */
507int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem) 507int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
@@ -511,7 +511,7 @@ int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
511 mutex_lock(&balloon_mutex); 511 mutex_lock(&balloon_mutex);
512 while (pgno < nr_pages) { 512 while (pgno < nr_pages) {
513 page = balloon_retrieve(highmem); 513 page = balloon_retrieve(highmem);
514 if (page && PageHighMem(page) == highmem) { 514 if (page && (highmem || !PageHighMem(page))) {
515 pages[pgno++] = page; 515 pages[pgno++] = page;
516 } else { 516 } else {
517 enum bp_state st; 517 enum bp_state st;
diff --git a/drivers/xen/gntalloc.c b/drivers/xen/gntalloc.c
index f6832f46aea4..e1c4c6e5b469 100644
--- a/drivers/xen/gntalloc.c
+++ b/drivers/xen/gntalloc.c
@@ -135,7 +135,7 @@ static int add_grefs(struct ioctl_gntalloc_alloc_gref *op,
135 /* Grant foreign access to the page. */ 135 /* Grant foreign access to the page. */
136 gref->gref_id = gnttab_grant_foreign_access(op->domid, 136 gref->gref_id = gnttab_grant_foreign_access(op->domid,
137 pfn_to_mfn(page_to_pfn(gref->page)), readonly); 137 pfn_to_mfn(page_to_pfn(gref->page)), readonly);
138 if (gref->gref_id < 0) { 138 if ((int)gref->gref_id < 0) {
139 rc = gref->gref_id; 139 rc = gref->gref_id;
140 goto undo; 140 goto undo;
141 } 141 }
@@ -280,7 +280,7 @@ static long gntalloc_ioctl_alloc(struct gntalloc_file_private_data *priv,
280 goto out; 280 goto out;
281 } 281 }
282 282
283 gref_ids = kzalloc(sizeof(gref_ids[0]) * op.count, GFP_TEMPORARY); 283 gref_ids = kcalloc(op.count, sizeof(gref_ids[0]), GFP_TEMPORARY);
284 if (!gref_ids) { 284 if (!gref_ids) {
285 rc = -ENOMEM; 285 rc = -ENOMEM;
286 goto out; 286 goto out;
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 39871326afa2..afca14d9042e 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -114,11 +114,11 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
114 if (NULL == add) 114 if (NULL == add)
115 return NULL; 115 return NULL;
116 116
117 add->grants = kzalloc(sizeof(add->grants[0]) * count, GFP_KERNEL); 117 add->grants = kcalloc(count, sizeof(add->grants[0]), GFP_KERNEL);
118 add->map_ops = kzalloc(sizeof(add->map_ops[0]) * count, GFP_KERNEL); 118 add->map_ops = kcalloc(count, sizeof(add->map_ops[0]), GFP_KERNEL);
119 add->unmap_ops = kzalloc(sizeof(add->unmap_ops[0]) * count, GFP_KERNEL); 119 add->unmap_ops = kcalloc(count, sizeof(add->unmap_ops[0]), GFP_KERNEL);
120 add->kmap_ops = kzalloc(sizeof(add->kmap_ops[0]) * count, GFP_KERNEL); 120 add->kmap_ops = kcalloc(count, sizeof(add->kmap_ops[0]), GFP_KERNEL);
121 add->pages = kzalloc(sizeof(add->pages[0]) * count, GFP_KERNEL); 121 add->pages = kcalloc(count, sizeof(add->pages[0]), GFP_KERNEL);
122 if (NULL == add->grants || 122 if (NULL == add->grants ||
123 NULL == add->map_ops || 123 NULL == add->map_ops ||
124 NULL == add->unmap_ops || 124 NULL == add->unmap_ops ||
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 81c3ce6b8bbe..1906125eab49 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -35,6 +35,7 @@
35#include <linux/vmalloc.h> 35#include <linux/vmalloc.h>
36#include <linux/export.h> 36#include <linux/export.h>
37#include <asm/xen/hypervisor.h> 37#include <asm/xen/hypervisor.h>
38#include <asm/xen/page.h>
38#include <xen/interface/xen.h> 39#include <xen/interface/xen.h>
39#include <xen/interface/event_channel.h> 40#include <xen/interface/event_channel.h>
40#include <xen/events.h> 41#include <xen/events.h>
@@ -436,19 +437,20 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn);
436int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr) 437int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)
437{ 438{
438 struct gnttab_map_grant_ref op = { 439 struct gnttab_map_grant_ref op = {
439 .flags = GNTMAP_host_map, 440 .flags = GNTMAP_host_map | GNTMAP_contains_pte,
440 .ref = gnt_ref, 441 .ref = gnt_ref,
441 .dom = dev->otherend_id, 442 .dom = dev->otherend_id,
442 }; 443 };
443 struct vm_struct *area; 444 struct vm_struct *area;
445 pte_t *pte;
444 446
445 *vaddr = NULL; 447 *vaddr = NULL;
446 448
447 area = alloc_vm_area(PAGE_SIZE); 449 area = alloc_vm_area(PAGE_SIZE, &pte);
448 if (!area) 450 if (!area)
449 return -ENOMEM; 451 return -ENOMEM;
450 452
451 op.host_addr = (unsigned long)area->addr; 453 op.host_addr = arbitrary_virt_to_machine(pte).maddr;
452 454
453 if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)) 455 if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
454 BUG(); 456 BUG();
@@ -527,6 +529,7 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
527 struct gnttab_unmap_grant_ref op = { 529 struct gnttab_unmap_grant_ref op = {
528 .host_addr = (unsigned long)vaddr, 530 .host_addr = (unsigned long)vaddr,
529 }; 531 };
532 unsigned int level;
530 533
531 /* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr) 534 /* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr)
532 * method so that we don't have to muck with vmalloc internals here. 535 * method so that we don't have to muck with vmalloc internals here.
@@ -548,6 +551,8 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
548 } 551 }
549 552
550 op.handle = (grant_handle_t)area->phys_addr; 553 op.handle = (grant_handle_t)area->phys_addr;
554 op.host_addr = arbitrary_virt_to_machine(
555 lookup_address((unsigned long)vaddr, &level)).maddr;
551 556
552 if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)) 557 if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
553 BUG(); 558 BUG();
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 687fb11e2010..4bde182fcf93 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -119,7 +119,7 @@ unmap_kernel_range(unsigned long addr, unsigned long size)
119#endif 119#endif
120 120
121/* Allocate/destroy a 'vmalloc' VM area. */ 121/* Allocate/destroy a 'vmalloc' VM area. */
122extern struct vm_struct *alloc_vm_area(size_t size); 122extern struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes);
123extern void free_vm_area(struct vm_struct *area); 123extern void free_vm_area(struct vm_struct *area);
124 124
125/* for /dev/kmem */ 125/* for /dev/kmem */
diff --git a/include/xen/platform_pci.h b/include/xen/platform_pci.h
index a785a3b0c8c7..438c256c274b 100644
--- a/include/xen/platform_pci.h
+++ b/include/xen/platform_pci.h
@@ -29,8 +29,7 @@
29static inline int xen_must_unplug_nics(void) { 29static inline int xen_must_unplug_nics(void) {
30#if (defined(CONFIG_XEN_NETDEV_FRONTEND) || \ 30#if (defined(CONFIG_XEN_NETDEV_FRONTEND) || \
31 defined(CONFIG_XEN_NETDEV_FRONTEND_MODULE)) && \ 31 defined(CONFIG_XEN_NETDEV_FRONTEND_MODULE)) && \
32 (defined(CONFIG_XEN_PLATFORM_PCI) || \ 32 defined(CONFIG_XEN_PVHVM)
33 defined(CONFIG_XEN_PLATFORM_PCI_MODULE))
34 return 1; 33 return 1;
35#else 34#else
36 return 0; 35 return 0;
@@ -40,8 +39,7 @@ static inline int xen_must_unplug_nics(void) {
40static inline int xen_must_unplug_disks(void) { 39static inline int xen_must_unplug_disks(void) {
41#if (defined(CONFIG_XEN_BLKDEV_FRONTEND) || \ 40#if (defined(CONFIG_XEN_BLKDEV_FRONTEND) || \
42 defined(CONFIG_XEN_BLKDEV_FRONTEND_MODULE)) && \ 41 defined(CONFIG_XEN_BLKDEV_FRONTEND_MODULE)) && \
43 (defined(CONFIG_XEN_PLATFORM_PCI) || \ 42 defined(CONFIG_XEN_PVHVM)
44 defined(CONFIG_XEN_PLATFORM_PCI_MODULE))
45 return 1; 43 return 1;
46#else 44#else
47 return 0; 45 return 0;
diff --git a/mm/nommu.c b/mm/nommu.c
index 73419c55eda6..b982290fd962 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -454,7 +454,7 @@ void __attribute__((weak)) vmalloc_sync_all(void)
454 * between processes, it syncs the pagetable across all 454 * between processes, it syncs the pagetable across all
455 * processes. 455 * processes.
456 */ 456 */
457struct vm_struct *alloc_vm_area(size_t size) 457struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
458{ 458{
459 BUG(); 459 BUG();
460 return NULL; 460 return NULL;
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index b669aa6f6caf..3231bf332878 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -2141,23 +2141,30 @@ void __attribute__((weak)) vmalloc_sync_all(void)
2141 2141
2142static int f(pte_t *pte, pgtable_t table, unsigned long addr, void *data) 2142static int f(pte_t *pte, pgtable_t table, unsigned long addr, void *data)
2143{ 2143{
2144 /* apply_to_page_range() does all the hard work. */ 2144 pte_t ***p = data;
2145
2146 if (p) {
2147 *(*p) = pte;
2148 (*p)++;
2149 }
2145 return 0; 2150 return 0;
2146} 2151}
2147 2152
2148/** 2153/**
2149 * alloc_vm_area - allocate a range of kernel address space 2154 * alloc_vm_area - allocate a range of kernel address space
2150 * @size: size of the area 2155 * @size: size of the area
2156 * @ptes: returns the PTEs for the address space
2151 * 2157 *
2152 * Returns: NULL on failure, vm_struct on success 2158 * Returns: NULL on failure, vm_struct on success
2153 * 2159 *
2154 * This function reserves a range of kernel address space, and 2160 * This function reserves a range of kernel address space, and
2155 * allocates pagetables to map that range. No actual mappings 2161 * allocates pagetables to map that range. No actual mappings
2156 * are created. If the kernel address space is not shared 2162 * are created.
2157 * between processes, it syncs the pagetable across all 2163 *
2158 * processes. 2164 * If @ptes is non-NULL, pointers to the PTEs (in init_mm)
2165 * allocated for the VM area are returned.
2159 */ 2166 */
2160struct vm_struct *alloc_vm_area(size_t size) 2167struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)
2161{ 2168{
2162 struct vm_struct *area; 2169 struct vm_struct *area;
2163 2170
@@ -2171,19 +2178,11 @@ struct vm_struct *alloc_vm_area(size_t size)
2171 * of kernel virtual address space and mapped into init_mm. 2178 * of kernel virtual address space and mapped into init_mm.
2172 */ 2179 */
2173 if (apply_to_page_range(&init_mm, (unsigned long)area->addr, 2180 if (apply_to_page_range(&init_mm, (unsigned long)area->addr,
2174 area->size, f, NULL)) { 2181 size, f, ptes ? &ptes : NULL)) {
2175 free_vm_area(area); 2182 free_vm_area(area);
2176 return NULL; 2183 return NULL;
2177 } 2184 }
2178 2185
2179 /*
2180 * If the allocated address space is passed to a hypercall
2181 * before being used then we cannot rely on a page fault to
2182 * trigger an update of the page tables. So sync all the page
2183 * tables here.
2184 */
2185 vmalloc_sync_all();
2186
2187 return area; 2186 return area;
2188} 2187}
2189EXPORT_SYMBOL_GPL(alloc_vm_area); 2188EXPORT_SYMBOL_GPL(alloc_vm_area);