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

xen: make grant table arch portable

split out x86 specific part from grant-table.c and
allow ia64/xen specific initialization.
ia64/xen grant table is based on pseudo physical address
(guest physical address) unlike x86/xen. On ia64 init_mm
doesn't map identity straight mapped area.
ia64/xen specific grant table initialization is necessary.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

authored by

Isaku Yamahata and committed by
Ingo Molnar
8d3d2106 5f0ababb

+101 -33
+1 -1
arch/x86/xen/Makefile
··· 1 1 obj-y := enlighten.o setup.o multicalls.o mmu.o \ 2 - time.o manage.o xen-asm.o 2 + time.o manage.o xen-asm.o grant-table.o 3 3 4 4 obj-$(CONFIG_SMP) += smp.o
+91
arch/x86/xen/grant-table.c
··· 1 + /****************************************************************************** 2 + * grant_table.c 3 + * x86 specific part 4 + * 5 + * Granting foreign access to our memory reservation. 6 + * 7 + * Copyright (c) 2005-2006, Christopher Clark 8 + * Copyright (c) 2004-2005, K A Fraser 9 + * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> 10 + * VA Linux Systems Japan. Split out x86 specific part. 11 + * 12 + * This program is free software; you can redistribute it and/or 13 + * modify it under the terms of the GNU General Public License version 2 14 + * as published by the Free Software Foundation; or, when distributed 15 + * separately from the Linux kernel or incorporated into other 16 + * software packages, subject to the following license: 17 + * 18 + * Permission is hereby granted, free of charge, to any person obtaining a copy 19 + * of this source file (the "Software"), to deal in the Software without 20 + * restriction, including without limitation the rights to use, copy, modify, 21 + * merge, publish, distribute, sublicense, and/or sell copies of the Software, 22 + * and to permit persons to whom the Software is furnished to do so, subject to 23 + * the following conditions: 24 + * 25 + * The above copyright notice and this permission notice shall be included in 26 + * all copies or substantial portions of the Software. 27 + * 28 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 29 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 30 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 31 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 32 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 33 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 34 + * IN THE SOFTWARE. 35 + */ 36 + 37 + #include <linux/sched.h> 38 + #include <linux/mm.h> 39 + #include <linux/vmalloc.h> 40 + 41 + #include <xen/interface/xen.h> 42 + #include <xen/page.h> 43 + #include <xen/grant_table.h> 44 + 45 + #include <asm/pgtable.h> 46 + 47 + static int map_pte_fn(pte_t *pte, struct page *pmd_page, 48 + unsigned long addr, void *data) 49 + { 50 + unsigned long **frames = (unsigned long **)data; 51 + 52 + set_pte_at(&init_mm, addr, pte, mfn_pte((*frames)[0], PAGE_KERNEL)); 53 + (*frames)++; 54 + return 0; 55 + } 56 + 57 + static int unmap_pte_fn(pte_t *pte, struct page *pmd_page, 58 + unsigned long addr, void *data) 59 + { 60 + 61 + set_pte_at(&init_mm, addr, pte, __pte(0)); 62 + return 0; 63 + } 64 + 65 + int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, 66 + unsigned long max_nr_gframes, 67 + struct grant_entry **__shared) 68 + { 69 + int rc; 70 + struct grant_entry *shared = *__shared; 71 + 72 + if (shared == NULL) { 73 + struct vm_struct *area = 74 + xen_alloc_vm_area(PAGE_SIZE * max_nr_gframes); 75 + BUG_ON(area == NULL); 76 + shared = area->addr; 77 + *__shared = shared; 78 + } 79 + 80 + rc = apply_to_page_range(&init_mm, (unsigned long)shared, 81 + PAGE_SIZE * nr_gframes, 82 + map_pte_fn, &frames); 83 + return rc; 84 + } 85 + 86 + void arch_gnttab_unmap_shared(struct grant_entry *shared, 87 + unsigned long nr_gframes) 88 + { 89 + apply_to_page_range(&init_mm, (unsigned long)shared, 90 + PAGE_SIZE * nr_gframes, unmap_pte_fn, NULL); 91 + }
+3 -32
drivers/xen/grant-table.c
··· 439 439 return xen_max; 440 440 } 441 441 442 - static int map_pte_fn(pte_t *pte, struct page *pmd_page, 443 - unsigned long addr, void *data) 444 - { 445 - unsigned long **frames = (unsigned long **)data; 446 - 447 - set_pte_at(&init_mm, addr, pte, mfn_pte((*frames)[0], PAGE_KERNEL)); 448 - (*frames)++; 449 - return 0; 450 - } 451 - 452 - static int unmap_pte_fn(pte_t *pte, struct page *pmd_page, 453 - unsigned long addr, void *data) 454 - { 455 - 456 - set_pte_at(&init_mm, addr, pte, __pte(0)); 457 - return 0; 458 - } 459 - 460 442 static int gnttab_map(unsigned int start_idx, unsigned int end_idx) 461 443 { 462 444 struct gnttab_setup_table setup; ··· 462 480 463 481 BUG_ON(rc || setup.status); 464 482 465 - if (shared == NULL) { 466 - struct vm_struct *area; 467 - area = xen_alloc_vm_area(PAGE_SIZE * max_nr_grant_frames()); 468 - BUG_ON(area == NULL); 469 - shared = area->addr; 470 - } 471 - rc = apply_to_page_range(&init_mm, (unsigned long)shared, 472 - PAGE_SIZE * nr_gframes, 473 - map_pte_fn, &frames); 483 + rc = arch_gnttab_map_shared(frames, nr_gframes, max_nr_grant_frames(), 484 + &shared); 474 485 BUG_ON(rc); 475 - frames -= nr_gframes; /* adjust after map_pte_fn() */ 476 486 477 487 kfree(frames); 478 488 ··· 480 506 481 507 static int gnttab_suspend(void) 482 508 { 483 - apply_to_page_range(&init_mm, (unsigned long)shared, 484 - PAGE_SIZE * nr_grant_frames, 485 - unmap_pte_fn, NULL); 486 - 509 + arch_gnttab_unmap_shared(shared, nr_grant_frames); 487 510 return 0; 488 511 } 489 512
+6
include/xen/grant_table.h
··· 103 103 void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid, 104 104 unsigned long pfn); 105 105 106 + int arch_gnttab_map_shared(unsigned long *frames, unsigned long nr_gframes, 107 + unsigned long max_nr_gframes, 108 + struct grant_entry **__shared); 109 + void arch_gnttab_unmap_shared(struct grant_entry *shared, 110 + unsigned long nr_gframes); 111 + 106 112 #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) 107 113 108 114 #endif /* __ASM_GNTTAB_H__ */