aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2011-09-29 11:53:32 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-11-16 12:13:08 -0500
commitcd12909cb576d37311fe35868780e82d5007d0c8 (patch)
tree70ec60af4feb32087f542a838fe4dce8717f0cd6 /drivers/xen
parent1ea6b8f48918282bdca0b32a34095504ee65bab5 (diff)
xen: map foreign pages for shared rings by updating the PTEs directly
When mapping a foreign page with xenbus_map_ring_valloc() with the GNTTABOP_map_grant_ref hypercall, set the GNTMAP_contains_pte flag and pass a pointer to the PTE (in init_mm). After the page is mapped, the usual fault mechanism can be used to update additional MMs. This allows the vmalloc_sync_all() to be removed from alloc_vm_area(). Signed-off-by: David Vrabel <david.vrabel@citrix.com> Acked-by: Andrew Morton <akpm@linux-foundation.org> [v1: Squashed fix by Michal for no-mmu case] Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Signed-off-by: Michal Simek <monstr@monstr.eu>
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/xenbus/xenbus_client.c11
1 files changed, 8 insertions, 3 deletions
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();