diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-09-08 19:15:11 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-09-08 19:15:11 +0100 |
commit | cda30a2a6cfeab9b3c63d20d9ea1ceb7760aa4e9 (patch) | |
tree | ec08c2f30e252e0b43d39033670afcf45994d6e6 /unmodified_drivers | |
parent | 06b8f9d3ab6844053e108d533852edc2ff4a5399 (diff) | |
download | xen-cda30a2a6cfeab9b3c63d20d9ea1ceb7760aa4e9.tar.gz xen-cda30a2a6cfeab9b3c63d20d9ea1ceb7760aa4e9.tar.bz2 xen-cda30a2a6cfeab9b3c63d20d9ea1ceb7760aa4e9.zip |
[HVM] pv drivers: Allocate hypercall area as an executable region.
We have to use __vmalloc() and __PAGE_KERNEL because vmalloc_exec()
and PAGE_KERNEL_EXEC are not exported to modules.
Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'unmodified_drivers')
-rw-r--r-- | unmodified_drivers/linux-2.6/platform-pci/platform-pci.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c index f1def20b3b..6527b18e80 100644 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c @@ -17,6 +17,7 @@ * Place - Suite 330, Boston, MA 02111-1307 USA. * */ + #include <linux/module.h> #include <linux/kernel.h> #include <linux/sched.h> @@ -25,6 +26,8 @@ #include <linux/init.h> #include <linux/version.h> #include <linux/interrupt.h> +#include <linux/vmalloc.h> +#include <linux/mm.h> #include <asm/system.h> #include <asm/io.h> #include <asm/irq.h> @@ -47,7 +50,6 @@ MODULE_AUTHOR("ssmith@xensource.com"); MODULE_DESCRIPTION("Xen platform PCI device"); MODULE_LICENSE("GPL"); - unsigned long *phys_to_machine_mapping; EXPORT_SYMBOL(phys_to_machine_mapping); @@ -118,7 +120,7 @@ unsigned long alloc_xen_mmio(unsigned long len) /* Lifted from hvmloader.c */ static int get_hypercall_stubs(void) { - uint32_t eax, ebx, ecx, edx, pages, msr, order, i; + uint32_t eax, ebx, ecx, edx, pages, msr, i; char signature[13]; cpuid(0x40000000, &eax, &ebx, &ecx, &edx); @@ -141,22 +143,22 @@ static int get_hypercall_stubs(void) cpuid(0x40000002, &pages, &msr, &ecx, &edx); - i = pages - 1; - for (order = 0; i != 0; order++) - i >>= 1; + printk(KERN_INFO "Hypercall area is %u pages.\n", pages); - printk(KERN_INFO "Hypercall area is %u pages (order %u allocation)\n", - pages, order); - - hypercall_stubs = (void *)__get_free_pages(GFP_KERNEL, order); + /* Use __vmalloc() because vmalloc_exec() is not an exported symbol. */ + /* PAGE_KERNEL_EXEC also is not exported, hence we use PAGE_KERNEL. */ + /* hypercall_stubs = vmalloc_exec(pages * PAGE_SIZE); */ + hypercall_stubs = __vmalloc(pages * PAGE_SIZE, + GFP_KERNEL | __GFP_HIGHMEM, + __pgprot(__PAGE_KERNEL & ~_PAGE_NX)); if (hypercall_stubs == NULL) return -ENOMEM; - for (i = 0; i < pages; i++) - wrmsrl(msr, - virt_to_phys(hypercall_stubs) + /* base address */ - (i << PAGE_SHIFT) + /* offset of page @i */ - i); /* request page @i */ + for (i = 0; i < pages; i++) { + unsigned long pfn; + pfn = vmalloc_to_pfn((char *)hypercall_stubs + i*PAGE_SIZE); + wrmsrl(msr, ((u64)pfn << PAGE_SHIFT) + i); + } return 0; } |