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

[Xen-changelog] [xen stable-4.2] ACPI/APEI: fix ERST MOVE_DATA instruction implementation



commit a44b0a5538c26f993b72fbd083c3d3c216fa8ca8
Author:     Huang Ying <ying.huang@xxxxxxxxx>
AuthorDate: Tue Apr 2 10:58:31 2013 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Apr 2 10:58:31 2013 +0200

    ACPI/APEI: fix ERST MOVE_DATA instruction implementation
    
    The src_base and dst_base fields in apei_exec_context are physical
    address, so they should be ioremaped before being used in ERST
    MOVE_DATA instruction.
    
    Reported-by: Javier Martinez Canillas <martinez.javier@xxxxxxxxx>
    Reported-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx>
    Signed-off-by: Huang Ying <ying.huang@xxxxxxxxx>
    
    Replace use of ioremap() by __acpi_map_table()/set_fixmap(). Fix error
    handling.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Keir Fraser <keir@xxxxxxx>
    master changeset: df2cf6a726b815fafa12e503c9a36707c3962f22
    master date: 2012-10-17 14:12:06 +0200
---
 xen/drivers/acpi/apei/erst.c |   57 +++++++++++++++++++++++++++++++++++++++---
 1 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/xen/drivers/acpi/apei/erst.c b/xen/drivers/acpi/apei/erst.c
index eb666a6..46fcff5 100644
--- a/xen/drivers/acpi/apei/erst.c
+++ b/xen/drivers/acpi/apei/erst.c
@@ -247,15 +247,64 @@ static int erst_exec_move_data(struct apei_exec_context 
*ctx,
 {
        int rc;
        u64 offset;
+#ifdef CONFIG_X86
+       enum fixed_addresses idx;
+#endif
+       void *src, *dst;
+
+       /* ioremap does not work in interrupt context */
+       if (in_irq()) {
+               printk(KERN_WARNING
+                      "MOVE_DATA cannot be used in interrupt context\n");
+               return -EBUSY;
+       }
 
        rc = __apei_exec_read_register(entry, &offset);
        if (rc)
                return rc;
-       memmove((void *)(unsigned long)(ctx->dst_base + offset),
-               (void *)(unsigned long)(ctx->src_base + offset),
-               ctx->var2);
 
-       return 0;
+#ifdef CONFIG_X86
+       switch (ctx->var2) {
+       case 0:
+               return 0;
+       case 1 ... PAGE_SIZE:
+               break;
+       default:
+               printk(KERN_WARNING
+                      "MOVE_DATA cannot be used for %#"PRIx64" bytes of 
data\n",
+                      ctx->var2);
+               return -EOPNOTSUPP;
+       }
+
+       src = __acpi_map_table(ctx->src_base + offset, ctx->var2);
+#else
+       src = ioremap(ctx->src_base + offset, ctx->var2);
+#endif
+       if (!src)
+               return -ENOMEM;
+
+#ifdef CONFIG_X86
+       BUILD_BUG_ON(FIX_ACPI_PAGES < 4);
+       idx = virt_to_fix((unsigned long)src + 2 * PAGE_SIZE);
+       offset += ctx->dst_base;
+       dst = (void *)fix_to_virt(idx) + (offset & ~PAGE_MASK);
+       set_fixmap(idx, offset);
+       if (PFN_DOWN(offset) != PFN_DOWN(offset + ctx->var2 - 1)) {
+               idx = virt_to_fix((unsigned long)dst + PAGE_SIZE);
+               set_fixmap(idx, offset + PAGE_SIZE);
+       }
+#else
+       dst = ioremap(ctx->dst_base + offset, ctx->var2);
+#endif
+       if (dst) {
+               memmove(dst, src, ctx->var2);
+               iounmap(dst);
+       } else
+               rc = -ENOMEM;
+
+       iounmap(src);
+
+       return rc;
 }
 
 static struct apei_exec_ins_type erst_ins_type[] = {
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.2

_______________________________________________
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®.