]> xenbits.xensource.com Git - xen.git/commitdiff
ACPI: fix acpi_os_map_memory()
authorJan Beulich <jbeulich@suse.com>
Wed, 21 Aug 2013 06:38:40 +0000 (08:38 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 21 Aug 2013 06:38:40 +0000 (08:38 +0200)
It using map_domain_page() was entirely wrong. Use __acpi_map_table()
instead for the time being, with locking added as the mappings it
produces get replaced with subsequent invocations. Using locking in
this way is acceptable here since the only two runtime callers are
acpi_os_{read,write}_memory(), which don't leave mappings pending upon
returning to their callers.

Also fix __acpi_map_table()'s first parameter's type - while benign for
unstable, backports to pre-4.3 trees will need this.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/acpi/lib.c
xen/drivers/acpi/osl.c
xen/include/xen/acpi.h

index e8e69d1cb4934c94044af29d3e89fbdb076a12cc..1f98c316c3030f01436bef7903bf0caccdb18359 100644 (file)
@@ -39,7 +39,7 @@ u32 __read_mostly x86_acpiid_to_apicid[MAX_MADT_ENTRIES] =
  * from the fixed base.  That's why we start at FIX_ACPI_END and
  * count idx down while incrementing the phys address.
  */
-char *__acpi_map_table(unsigned long phys, unsigned long size)
+char *__acpi_map_table(paddr_t phys, unsigned long size)
 {
        unsigned long base, offset, mapped_size;
        int idx;
index 1b60be621cced25a794e27fa9d15a39f3df3703e..4cba3c06cb833af9f427337f25ba5d6a75c1a262 100644 (file)
@@ -83,14 +83,20 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
        }
 }
 
-void __iomem *__init
+static DEFINE_SPINLOCK(map_lock);
+
+void __iomem *
 acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
 {
-       return __acpi_map_table((unsigned long)phys, size);
+       if (system_state >= SYS_STATE_active)
+               spin_lock(&map_lock);
+       return __acpi_map_table(phys, size);
 }
 
-void __init acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
+void acpi_os_unmap_memory(void __iomem * virt, acpi_size size)
 {
+       if (system_state >= SYS_STATE_active)
+               spin_unlock(&map_lock);
 }
 
 acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
@@ -133,9 +139,8 @@ acpi_status
 acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
 {
        u32 dummy;
-       void __iomem *virt_addr;
+       void __iomem *virt_addr = acpi_os_map_memory(phys_addr, width >> 3);
 
-       virt_addr = map_domain_page(phys_addr>>PAGE_SHIFT);
        if (!value)
                value = &dummy;
 
@@ -153,7 +158,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
                BUG();
        }
 
-       unmap_domain_page(virt_addr);
+       acpi_os_unmap_memory(virt_addr, width >> 3);
 
        return AE_OK;
 }
@@ -161,9 +166,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width)
 acpi_status
 acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
 {
-       void __iomem *virt_addr;
-
-       virt_addr = map_domain_page(phys_addr>>PAGE_SHIFT);
+       void __iomem *virt_addr = acpi_os_map_memory(phys_addr, width >> 3);
 
        switch (width) {
        case 8:
@@ -179,7 +182,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width)
                BUG();
        }
 
-       unmap_domain_page(virt_addr);
+       acpi_os_unmap_memory(virt_addr, width >> 3);
 
        return AE_OK;
 }
index 8f3cdca3141d53b1deca0678112b69161b91ed20..aedec65a28a7a88edb13fdd08491442cf6396a57 100644 (file)
@@ -56,7 +56,7 @@ typedef int (*acpi_table_handler) (struct acpi_table_header *table);
 typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
 
 unsigned int acpi_get_processor_id (unsigned int cpu);
-char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
+char * __acpi_map_table (paddr_t phys_addr, unsigned long size);
 int acpi_boot_init (void);
 int acpi_boot_table_init (void);
 int acpi_numa_init (void);