[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen stable-4.3] ACPI: fix acpi_os_map_memory()



commit f37de503d4d580b4fa3c04965e9dc416c040cab5
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Tue Aug 27 15:24:31 2013 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Aug 27 15:24:31 2013 +0200

    ACPI: fix acpi_os_map_memory()
    
    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@xxxxxxxx>
    
    ACPI: use ioremap() in acpi_os_map_memory()
    
    This drops the post-boot use of __acpi_map_table() here again (together
    with the somewhat awkward locking), in favor of using ioremap().
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    master commit: 2ee9cbf9d8eaeff6e21222905d22dbd58dc5fe29
    master date: 2013-08-21 08:38:40 +0200
    master commit: c5ba8ed4c6f005d332a49d93a3ef8ff2b690b256
    master date: 2013-08-21 08:40:22 +0200
---
 xen/arch/x86/acpi/lib.c |    2 +-
 xen/drivers/acpi/osl.c  |   29 +++++++++++++++++++----------
 xen/include/xen/acpi.h  |    2 +-
 3 files changed, 21 insertions(+), 12 deletions(-)

diff --git a/xen/arch/x86/acpi/lib.c b/xen/arch/x86/acpi/lib.c
index e8e69d1..1f98c31 100644
--- a/xen/arch/x86/acpi/lib.c
+++ b/xen/arch/x86/acpi/lib.c
@@ -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;
diff --git a/xen/drivers/acpi/osl.c b/xen/drivers/acpi/osl.c
index 1b60be6..93c983c 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,14 +84,25 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
        }
 }
 
-void __iomem *__init
+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) {
+               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 __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)
+               vunmap((void *)((unsigned long)virt & PAGE_MASK));
 }
 
 acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
@@ -133,9 +145,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 +164,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 +172,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 +188,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;
 }
diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h
index 8f3cdca..aedec65 100644
--- a/xen/include/xen/acpi.h
+++ b/xen/include/xen/acpi.h
@@ -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);
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.3

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.