diff options
| -rw-r--r-- | arch/x86/xen/Makefile | 2 | ||||
| -rw-r--r-- | arch/x86/xen/grant-table.c | 91 | ||||
| -rw-r--r-- | drivers/xen/grant-table.c | 35 | ||||
| -rw-r--r-- | include/xen/grant_table.h | 6 |
4 files changed, 101 insertions, 33 deletions
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index 95c59260dccb..3d8df981d5fd 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | obj-y := enlighten.o setup.o multicalls.o mmu.o \ | 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 | obj-$(CONFIG_SMP) += smp.o | 4 | obj-$(CONFIG_SMP) += smp.o |
diff --git a/arch/x86/xen/grant-table.c b/arch/x86/xen/grant-table.c new file mode 100644 index 000000000000..49ba9b5224d1 --- /dev/null +++ b/arch/x86/xen/grant-table.c | |||
| @@ -0,0 +1,91 @@ | |||
| 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 | } | ||
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 3e02808c4055..52b6b41b909d 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c | |||
| @@ -439,24 +439,6 @@ static inline unsigned int max_nr_grant_frames(void) | |||
| 439 | return xen_max; | 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 | static int gnttab_map(unsigned int start_idx, unsigned int end_idx) | 442 | static int gnttab_map(unsigned int start_idx, unsigned int end_idx) |
| 461 | { | 443 | { |
| 462 | struct gnttab_setup_table setup; | 444 | struct gnttab_setup_table setup; |
| @@ -480,17 +462,9 @@ static int gnttab_map(unsigned int start_idx, unsigned int end_idx) | |||
| 480 | 462 | ||
| 481 | BUG_ON(rc || setup.status); | 463 | BUG_ON(rc || setup.status); |
| 482 | 464 | ||
| 483 | if (shared == NULL) { | 465 | rc = arch_gnttab_map_shared(frames, nr_gframes, max_nr_grant_frames(), |
| 484 | struct vm_struct *area; | 466 | &shared); |
| 485 | area = xen_alloc_vm_area(PAGE_SIZE * max_nr_grant_frames()); | ||
| 486 | BUG_ON(area == NULL); | ||
| 487 | shared = area->addr; | ||
| 488 | } | ||
| 489 | rc = apply_to_page_range(&init_mm, (unsigned long)shared, | ||
| 490 | PAGE_SIZE * nr_gframes, | ||
| 491 | map_pte_fn, &frames); | ||
| 492 | BUG_ON(rc); | 467 | BUG_ON(rc); |
| 493 | frames -= nr_gframes; /* adjust after map_pte_fn() */ | ||
| 494 | 468 | ||
| 495 | kfree(frames); | 469 | kfree(frames); |
| 496 | 470 | ||
| @@ -506,10 +480,7 @@ static int gnttab_resume(void) | |||
| 506 | 480 | ||
| 507 | static int gnttab_suspend(void) | 481 | static int gnttab_suspend(void) |
| 508 | { | 482 | { |
| 509 | apply_to_page_range(&init_mm, (unsigned long)shared, | 483 | arch_gnttab_unmap_shared(shared, nr_grant_frames); |
| 510 | PAGE_SIZE * nr_grant_frames, | ||
| 511 | unmap_pte_fn, NULL); | ||
| 512 | |||
| 513 | return 0; | 484 | return 0; |
| 514 | } | 485 | } |
| 515 | 486 | ||
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h index d2822920d43e..466204846121 100644 --- a/include/xen/grant_table.h +++ b/include/xen/grant_table.h | |||
| @@ -103,6 +103,12 @@ void gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid, | |||
| 103 | void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid, | 103 | void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid, |
| 104 | unsigned long pfn); | 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 | #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) | 112 | #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr)) |
| 107 | 113 | ||
| 108 | #endif /* __ASM_GNTTAB_H__ */ | 114 | #endif /* __ASM_GNTTAB_H__ */ |
