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

[Xen-devel] [PATCH v4 09/15] x86/domctl: Handle ACPI access from domctl



Signed-off-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx>
---
Changes in v4:
* New patch

 xen/arch/x86/hvm/acpi.c | 61 +++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 54 insertions(+), 7 deletions(-)

diff --git a/xen/arch/x86/hvm/acpi.c b/xen/arch/x86/hvm/acpi.c
index c80c464..1c205eb 100644
--- a/xen/arch/x86/hvm/acpi.c
+++ b/xen/arch/x86/hvm/acpi.c
@@ -7,9 +7,11 @@
 #include <xen/lib.h>
 #include <xen/sched.h>
 
+#include <asm/guest_access.h>
+
 #include <public/arch-x86/xen.h>
 
-static int acpi_access_common(struct domain *d,
+static int acpi_access_common(struct domain *d, bool is_guest_access,
                               int dir, unsigned int port,
                               unsigned int bytes, uint32_t *val)
 {
@@ -87,8 +89,13 @@ static int acpi_access_common(struct domain *d,
     else
     {
         /* Guests do not write CPU map */
-        if ( !mask_sts )
-            return X86EMUL_UNHANDLEABLE;
+        if ( !is_guest_access && !mask_sts )
+        {
+            unsigned int first_byte = port - XEN_ACPI_CPU_MAP;
+
+            memcpy((uint8_t *)d->avail_vcpus + first_byte, val,
+                   min(bytes, ((d->max_vcpus + 7) / 8) - first_byte));
+        }
         else if ( mask_sts )
         {
             uint32_t v = *val;
@@ -97,14 +104,20 @@ static int acpi_access_common(struct domain *d,
             switch ( port & 3 )
             {
             case 0:
-                *sts &= ~(v & 0xff);
+                if ( is_guest_access )
+                    *sts &= ~(v & 0xff);
+                else
+                    *sts = (*sts & 0xff00) | (v & 0xff);
                 *sts &= *mask_sts;
                 if ( !--bytes )
                     break;
                 v >>= 8;
 
             case 1:
-                *sts &= ~((v & 0xff) << 8);
+                if ( is_guest_access )
+                    *sts &= ~((v & 0xff) << 8);
+                else
+                    *sts = ((v & 0xff) << 8) | (*sts & 0xff);
                 *sts &= *mask_sts;
                 if ( !--bytes )
                     break;
@@ -128,13 +141,47 @@ static int acpi_access_common(struct domain *d,
 int hvm_acpi_domctl_access(struct domain *d, uint8_t rw, gas_t *gas,
                            XEN_GUEST_HANDLE_PARAM(uint8) arg)
 {
-    return -ENOSYS;
+    unsigned int port, tot_bytes, bytes;
+    unsigned int i;
+    uint32_t val;
+    uint8_t *ptr = (uint8_t *)&val;
+    int rc;
+
+    /*
+     * Only allow accesses to IO space. Accesses should be byte-aligned
+     * and integral number of bytes.
+     */
+    if ( gas->space_id != XEN_ACPI_SYSTEM_IO ||
+         gas->bit_width & 7 || gas->bit_offset & 7 )
+        return -EINVAL;
+
+    port = gas->address + (gas->bit_offset >> 3);
+    tot_bytes = gas->bit_width >> 3;
+
+    for ( i = 0; i < tot_bytes; i += sizeof(val) )
+    {
+        bytes = (tot_bytes - i > sizeof(val)) ? sizeof(val) : tot_bytes - i;
+
+        if ((rw == XEN_DOMCTL_ACPI_WRITE) &&
+            copy_from_guest_offset(ptr, arg, i, bytes))
+            return -EFAULT;
+
+        rc = acpi_access_common(d, false, rw, port + i, bytes, &val);
+        if ( rc )
+            return rc;
+
+        if ((rw == XEN_DOMCTL_ACPI_READ) &&
+            copy_to_guest_offset(arg, i, ptr, bytes))
+            return -EFAULT;
+    }
+
+    return 0;
 }
 
 static int acpi_guest_access(int dir, unsigned int port,
                              unsigned int bytes, uint32_t *val)
 {
-    return  acpi_access_common(current->domain,
+    return  acpi_access_common(current->domain, true,
                                (dir == IOREQ_READ) ?
                                XEN_DOMCTL_ACPI_READ: XEN_DOMCTL_ACPI_WRITE,
                                port, bytes, val);
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

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