diff for duplicates of <20111107203613.GA6546@phenom.dumpdata.com> diff --git a/a/2.txt b/N1/2.txt index c2bc26c..8b13789 100644 --- a/a/2.txt +++ b/N1/2.txt @@ -1,167 +1 @@ ->From 21396dbbb3f976c8b4deb9f696994458dbe00db0 Mon Sep 17 00:00:00 2001 -From: David Vrabel <david.vrabel@citrix.com> -Date: Thu, 29 Sep 2011 16:53:32 +0100 -Subject: [PATCH] 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> -Cc: Andrew Morton <akpm@linux-foundation.org> -Cc: Jeremy Fitzhardinge <jeremy@goop.org> -Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> ---- - arch/x86/xen/grant-table.c | 2 +- - drivers/xen/xenbus/xenbus_client.c | 11 ++++++++--- - include/linux/vmalloc.h | 2 +- - mm/vmalloc.c | 27 +++++++++++++-------------- - 4 files changed, 23 insertions(+), 19 deletions(-) - -diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c -index 6bbfd7a..5a40d24 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, - - if (shared == NULL) { - struct vm_struct *area = -- alloc_vm_area(PAGE_SIZE * max_nr_gframes); -+ alloc_vm_area(PAGE_SIZE * max_nr_gframes, NULL); - BUG_ON(area == NULL); - shared = area->addr; - *__shared = shared; -diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c -index 81c3ce6..1906125 100644 ---- a/drivers/xen/xenbus/xenbus_client.c -+++ b/drivers/xen/xenbus/xenbus_client.c -@@ -35,6 +35,7 @@ - #include <linux/vmalloc.h> - #include <linux/export.h> - #include <asm/xen/hypervisor.h> -+#include <asm/xen/page.h> - #include <xen/interface/xen.h> - #include <xen/interface/event_channel.h> - #include <xen/events.h> -@@ -436,19 +437,20 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn); - int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr) - { - struct gnttab_map_grant_ref op = { -- .flags = GNTMAP_host_map, -+ .flags = GNTMAP_host_map | GNTMAP_contains_pte, - .ref = gnt_ref, - .dom = dev->otherend_id, - }; - struct vm_struct *area; -+ pte_t *pte; - - *vaddr = NULL; - -- area = alloc_vm_area(PAGE_SIZE); -+ area = alloc_vm_area(PAGE_SIZE, &pte); - if (!area) - return -ENOMEM; - -- op.host_addr = (unsigned long)area->addr; -+ op.host_addr = arbitrary_virt_to_machine(pte).maddr; - - if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1)) - BUG(); -@@ -527,6 +529,7 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr) - struct gnttab_unmap_grant_ref op = { - .host_addr = (unsigned long)vaddr, - }; -+ unsigned int level; - - /* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr) - * 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) - } - - op.handle = (grant_handle_t)area->phys_addr; -+ op.host_addr = arbitrary_virt_to_machine( -+ lookup_address((unsigned long)vaddr, &level)).maddr; - - if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1)) - BUG(); -diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h -index 687fb11..4bde182 100644 ---- a/include/linux/vmalloc.h -+++ b/include/linux/vmalloc.h -@@ -119,7 +119,7 @@ unmap_kernel_range(unsigned long addr, unsigned long size) - #endif - - /* Allocate/destroy a 'vmalloc' VM area. */ --extern struct vm_struct *alloc_vm_area(size_t size); -+extern struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes); - extern void free_vm_area(struct vm_struct *area); - - /* for /dev/kmem */ -diff --git a/mm/vmalloc.c b/mm/vmalloc.c -index b669aa6..3231bf3 100644 ---- a/mm/vmalloc.c -+++ b/mm/vmalloc.c -@@ -2141,23 +2141,30 @@ void __attribute__((weak)) vmalloc_sync_all(void) - - static int f(pte_t *pte, pgtable_t table, unsigned long addr, void *data) - { -- /* apply_to_page_range() does all the hard work. */ -+ pte_t ***p = data; -+ -+ if (p) { -+ *(*p) = pte; -+ (*p)++; -+ } - return 0; - } - - /** - * alloc_vm_area - allocate a range of kernel address space - * @size: size of the area -+ * @ptes: returns the PTEs for the address space - * - * Returns: NULL on failure, vm_struct on success - * - * This function reserves a range of kernel address space, and - * allocates pagetables to map that range. No actual mappings -- * are created. If the kernel address space is not shared -- * between processes, it syncs the pagetable across all -- * processes. -+ * are created. -+ * -+ * If @ptes is non-NULL, pointers to the PTEs (in init_mm) -+ * allocated for the VM area are returned. - */ --struct vm_struct *alloc_vm_area(size_t size) -+struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes) - { - struct vm_struct *area; - -@@ -2171,19 +2178,11 @@ struct vm_struct *alloc_vm_area(size_t size) - * of kernel virtual address space and mapped into init_mm. - */ - if (apply_to_page_range(&init_mm, (unsigned long)area->addr, -- area->size, f, NULL)) { -+ size, f, ptes ? &ptes : NULL)) { - free_vm_area(area); - return NULL; - } - -- /* -- * If the allocated address space is passed to a hypercall -- * before being used then we cannot rely on a page fault to -- * trigger an update of the page tables. So sync all the page -- * tables here. -- */ -- vmalloc_sync_all(); -- - return area; - } - EXPORT_SYMBOL_GPL(alloc_vm_area); --- -1.7.7.1 diff --git a/a/content_digest b/N1/content_digest index 85a52c6..353273a 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -214,172 +214,5 @@ "\01:2\0" "fn\00001-xen-map-foreign-pages-for-shared-rings-by-updating-t.patch\0" "b\0" - ">From 21396dbbb3f976c8b4deb9f696994458dbe00db0 Mon Sep 17 00:00:00 2001\n" - "From: David Vrabel <david.vrabel@citrix.com>\n" - "Date: Thu, 29 Sep 2011 16:53:32 +0100\n" - "Subject: [PATCH] xen: map foreign pages for shared rings by updating the PTEs\n" - " directly\n" - "\n" - "When mapping a foreign page with xenbus_map_ring_valloc() with the\n" - "GNTTABOP_map_grant_ref hypercall, set the GNTMAP_contains_pte flag and\n" - "pass a pointer to the PTE (in init_mm).\n" - "\n" - "After the page is mapped, the usual fault mechanism can be used to\n" - "update additional MMs. This allows the vmalloc_sync_all() to be\n" - "removed from alloc_vm_area().\n" - "\n" - "Signed-off-by: David Vrabel <david.vrabel@citrix.com>\n" - "Cc: Andrew Morton <akpm@linux-foundation.org>\n" - "Cc: Jeremy Fitzhardinge <jeremy@goop.org>\n" - "Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>\n" - "---\n" - " arch/x86/xen/grant-table.c | 2 +-\n" - " drivers/xen/xenbus/xenbus_client.c | 11 ++++++++---\n" - " include/linux/vmalloc.h | 2 +-\n" - " mm/vmalloc.c | 27 +++++++++++++--------------\n" - " 4 files changed, 23 insertions(+), 19 deletions(-)\n" - "\n" - "diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c\n" - "index 6bbfd7a..5a40d24 100644\n" - "--- a/arch/x86/xen/grant-table.c\n" - "+++ b/arch/x86/xen/grant-table.c\n" - "@@ -71,7 +71,7 @@ int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes,\n" - " \n" - " \tif (shared == NULL) {\n" - " \t\tstruct vm_struct *area =\n" - "-\t\t\talloc_vm_area(PAGE_SIZE * max_nr_gframes);\n" - "+\t\t\talloc_vm_area(PAGE_SIZE * max_nr_gframes, NULL);\n" - " \t\tBUG_ON(area == NULL);\n" - " \t\tshared = area->addr;\n" - " \t\t*__shared = shared;\n" - "diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c\n" - "index 81c3ce6..1906125 100644\n" - "--- a/drivers/xen/xenbus/xenbus_client.c\n" - "+++ b/drivers/xen/xenbus/xenbus_client.c\n" - "@@ -35,6 +35,7 @@\n" - " #include <linux/vmalloc.h>\n" - " #include <linux/export.h>\n" - " #include <asm/xen/hypervisor.h>\n" - "+#include <asm/xen/page.h>\n" - " #include <xen/interface/xen.h>\n" - " #include <xen/interface/event_channel.h>\n" - " #include <xen/events.h>\n" - "@@ -436,19 +437,20 @@ EXPORT_SYMBOL_GPL(xenbus_free_evtchn);\n" - " int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)\n" - " {\n" - " \tstruct gnttab_map_grant_ref op = {\n" - "-\t\t.flags = GNTMAP_host_map,\n" - "+\t\t.flags = GNTMAP_host_map | GNTMAP_contains_pte,\n" - " \t\t.ref = gnt_ref,\n" - " \t\t.dom = dev->otherend_id,\n" - " \t};\n" - " \tstruct vm_struct *area;\n" - "+\tpte_t *pte;\n" - " \n" - " \t*vaddr = NULL;\n" - " \n" - "-\tarea = alloc_vm_area(PAGE_SIZE);\n" - "+\tarea = alloc_vm_area(PAGE_SIZE, &pte);\n" - " \tif (!area)\n" - " \t\treturn -ENOMEM;\n" - " \n" - "-\top.host_addr = (unsigned long)area->addr;\n" - "+\top.host_addr = arbitrary_virt_to_machine(pte).maddr;\n" - " \n" - " \tif (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))\n" - " \t\tBUG();\n" - "@@ -527,6 +529,7 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)\n" - " \tstruct gnttab_unmap_grant_ref op = {\n" - " \t\t.host_addr = (unsigned long)vaddr,\n" - " \t};\n" - "+\tunsigned int level;\n" - " \n" - " \t/* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr)\n" - " \t * method so that we don't have to muck with vmalloc internals here.\n" - "@@ -548,6 +551,8 @@ int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)\n" - " \t}\n" - " \n" - " \top.handle = (grant_handle_t)area->phys_addr;\n" - "+\top.host_addr = arbitrary_virt_to_machine(\n" - "+\t\tlookup_address((unsigned long)vaddr, &level)).maddr;\n" - " \n" - " \tif (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))\n" - " \t\tBUG();\n" - "diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h\n" - "index 687fb11..4bde182 100644\n" - "--- a/include/linux/vmalloc.h\n" - "+++ b/include/linux/vmalloc.h\n" - "@@ -119,7 +119,7 @@ unmap_kernel_range(unsigned long addr, unsigned long size)\n" - " #endif\n" - " \n" - " /* Allocate/destroy a 'vmalloc' VM area. */\n" - "-extern struct vm_struct *alloc_vm_area(size_t size);\n" - "+extern struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes);\n" - " extern void free_vm_area(struct vm_struct *area);\n" - " \n" - " /* for /dev/kmem */\n" - "diff --git a/mm/vmalloc.c b/mm/vmalloc.c\n" - "index b669aa6..3231bf3 100644\n" - "--- a/mm/vmalloc.c\n" - "+++ b/mm/vmalloc.c\n" - "@@ -2141,23 +2141,30 @@ void __attribute__((weak)) vmalloc_sync_all(void)\n" - " \n" - " static int f(pte_t *pte, pgtable_t table, unsigned long addr, void *data)\n" - " {\n" - "-\t/* apply_to_page_range() does all the hard work. */\n" - "+\tpte_t ***p = data;\n" - "+\n" - "+\tif (p) {\n" - "+\t\t*(*p) = pte;\n" - "+\t\t(*p)++;\n" - "+\t}\n" - " \treturn 0;\n" - " }\n" - " \n" - " /**\n" - " *\talloc_vm_area - allocate a range of kernel address space\n" - " *\t@size:\t\tsize of the area\n" - "+ *\t@ptes:\t\treturns the PTEs for the address space\n" - " *\n" - " *\tReturns:\tNULL on failure, vm_struct on success\n" - " *\n" - " *\tThis function reserves a range of kernel address space, and\n" - " *\tallocates pagetables to map that range. No actual mappings\n" - "- *\tare created. If the kernel address space is not shared\n" - "- *\tbetween processes, it syncs the pagetable across all\n" - "- *\tprocesses.\n" - "+ *\tare created.\n" - "+ *\n" - "+ *\tIf @ptes is non-NULL, pointers to the PTEs (in init_mm)\n" - "+ *\tallocated for the VM area are returned.\n" - " */\n" - "-struct vm_struct *alloc_vm_area(size_t size)\n" - "+struct vm_struct *alloc_vm_area(size_t size, pte_t **ptes)\n" - " {\n" - " \tstruct vm_struct *area;\n" - " \n" - "@@ -2171,19 +2178,11 @@ struct vm_struct *alloc_vm_area(size_t size)\n" - " \t * of kernel virtual address space and mapped into init_mm.\n" - " \t */\n" - " \tif (apply_to_page_range(&init_mm, (unsigned long)area->addr,\n" - "-\t\t\t\tarea->size, f, NULL)) {\n" - "+\t\t\t\tsize, f, ptes ? &ptes : NULL)) {\n" - " \t\tfree_vm_area(area);\n" - " \t\treturn NULL;\n" - " \t}\n" - " \n" - "-\t/*\n" - "-\t * If the allocated address space is passed to a hypercall\n" - "-\t * before being used then we cannot rely on a page fault to\n" - "-\t * trigger an update of the page tables. So sync all the page\n" - "-\t * tables here.\n" - "-\t */\n" - "-\tvmalloc_sync_all();\n" - "-\n" - " \treturn area;\n" - " }\n" - " EXPORT_SYMBOL_GPL(alloc_vm_area);\n" - "-- \n" - 1.7.7.1 -0d341b97b38a4649caa01d14508cce3b6cdabe230eedf6a6da799d8d84adbc75 +65aeb4481e44efe01908f4dabb098f37f99881c957b88ecc17f2201151be7f93
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.