diff options
-rw-r--r-- | xen/drivers/acpi/osl.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/xen/drivers/acpi/osl.c b/xen/drivers/acpi/osl.c index 4cba3c06cb..93c983ca9d 100644 --- a/xen/drivers/acpi/osl.c +++ b/xen/drivers/acpi/osl.c @@ -38,6 +38,7 @@ #include <xen/spinlock.h> #include <xen/domain_page.h> #include <xen/efi.h> +#include <xen/vmap.h> #define _COMPONENT ACPI_OS_SERVICES ACPI_MODULE_NAME("osl") @@ -83,20 +84,25 @@ acpi_physical_address __init acpi_os_get_root_pointer(void) } } -static DEFINE_SPINLOCK(map_lock); - void __iomem * acpi_os_map_memory(acpi_physical_address phys, acpi_size size) { - if (system_state >= SYS_STATE_active) - spin_lock(&map_lock); + if (system_state >= SYS_STATE_active) { + unsigned long pfn = PFN_DOWN(phys); + unsigned int offs = phys & (PAGE_SIZE - 1); + + /* The low first Mb is always mapped. */ + if ( !((phys + size - 1) >> 20) ) + return __va(phys); + return __vmap(&pfn, PFN_UP(offs + size), 1, 1, PAGE_HYPERVISOR_NOCACHE) + offs; + } return __acpi_map_table(phys, size); } void acpi_os_unmap_memory(void __iomem * virt, acpi_size size) { if (system_state >= SYS_STATE_active) - spin_unlock(&map_lock); + vunmap((void *)((unsigned long)virt & PAGE_MASK)); } acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width) |