diff mbox

[v5,03/13] domctl: Add XEN_DOMCTL_acpi_access

Message ID 1481930319-4796-4-git-send-email-boris.ostrovsky@oracle.com (mailing list archive)
State New, archived
Headers show

Commit Message

Boris Ostrovsky Dec. 16, 2016, 11:18 p.m. UTC
This domctl will allow toolstack to read and write some
ACPI registers. It will be available to both x86 and ARM
but will be implemented first only for x86

Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
---
CC: Daniel De Graaf <dgdegra@tycho.nsa.gov>
---
Changes in v5:
* Added forgotten in v4 xsm hooks
* Replaces gas_t with a xen_acpi_access_t
* Added structure padding
* Changed xen_domctl_acpi_access.val from uint8* to void*
* Constified hvm_acpi_domctl_access access pointer

 tools/flask/policy/modules/dom0.te  |  2 +-
 tools/flask/policy/modules/xen.if   |  4 ++--
 xen/arch/x86/domctl.c               |  9 +++++++++
 xen/arch/x86/hvm/Makefile           |  1 +
 xen/arch/x86/hvm/acpi.c             | 25 +++++++++++++++++++++++++
 xen/include/asm-x86/hvm/domain.h    |  4 ++++
 xen/include/public/domctl.h         | 25 +++++++++++++++++++++++++
 xen/xsm/flask/hooks.c               |  3 +++
 xen/xsm/flask/policy/access_vectors |  2 ++
 9 files changed, 72 insertions(+), 3 deletions(-)
 create mode 100644 xen/arch/x86/hvm/acpi.c

Comments

Jan Beulich Dec. 19, 2016, 2:17 p.m. UTC | #1
>>> On 17.12.16 at 00:18, <boris.ostrovsky@oracle.com> wrote:
> --- a/xen/arch/x86/domctl.c
> +++ b/xen/arch/x86/domctl.c
> @@ -1425,6 +1425,15 @@ long arch_do_domctl(
>          }
>          break;
>  
> +    case XEN_DOMCTL_acpi_access:
> +        if ( !is_hvm_domain(d) )
> +            ret = -EINVAL;

I think it would be better to use some other, less frequently used
error code here.

> --- /dev/null
> +++ b/xen/arch/x86/hvm/acpi.c
> @@ -0,0 +1,25 @@
> +/* acpi.c: ACPI access handling
> + *
> + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
> + */
> +#include <xen/errno.h>
> +#include <xen/lib.h>
> +#include <xen/sched.h>
> +
> +
> +int hvm_acpi_domctl_access(struct domain *d, uint8_t rw,

Wouldn't "rw" better be bool internally?

> --- a/xen/include/public/domctl.h
> +++ b/xen/include/public/domctl.h
> @@ -1144,6 +1144,29 @@ struct xen_domctl_psr_cat_op {
>  typedef struct xen_domctl_psr_cat_op xen_domctl_psr_cat_op_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_domctl_psr_cat_op_t);
>  
> +/* ACPI access structure */
> +typedef struct xen_acpi_access {
> +#define XEN_ACPI_SYSTEM_MEMORY 0
> +#define XEN_ACPI_SYSTEM_IO     1
> +    uint8_t            space_id;           /* Address space */
> +    uint8_t            width;              /* Access size (bytes) */
> +    uint8_t            pad[6];
> +    uint64_aligned_t   address;            /* 64-bit address of register */
> +} xen_acpi_access_t;
> +
> +struct xen_domctl_acpi_access {
> +    xen_acpi_access_t  access;             /* IN: Register being accessed */
> +
> +#define XEN_DOMCTL_ACPI_READ   0
> +#define XEN_DOMCTL_ACPI_WRITE  1
> +    uint8_t    rw;                         /* IN: Read or write */
> +    uint8_t    pad[7];
> +
> +    XEN_GUEST_HANDLE_64(void) val;         /* IN/OUT: data */
> +};
> +typedef struct xen_domctl_acpi_access xen_domctl_acpi_access_t;
> +DEFINE_XEN_GUEST_HANDLE(xen_domctl_acpi_access_t);

Do you expect to use xen_acpi_access anywhere else? If not,
the overall amount of padding needed could be reduced by
folding both structures.

Jan
Boris Ostrovsky Dec. 19, 2016, 2:48 p.m. UTC | #2
On 12/19/2016 09:17 AM, Jan Beulich wrote:
>>>> On 17.12.16 at 00:18, <boris.ostrovsky@oracle.com> wrote:
>> --- a/xen/arch/x86/domctl.c
>> +++ b/xen/arch/x86/domctl.c
>> @@ -1425,6 +1425,15 @@ long arch_do_domctl(
>>          }
>>          break;
>>  
>> +    case XEN_DOMCTL_acpi_access:
>> +        if ( !is_hvm_domain(d) )
>> +            ret = -EINVAL;
> I think it would be better to use some other, less frequently used
> error code here.

ENODEV? (Because there is no ACPI "device" for PV guests)

>
>> --- /dev/null
>> +++ b/xen/arch/x86/hvm/acpi.c
>> @@ -0,0 +1,25 @@
>> +/* acpi.c: ACPI access handling
>> + *
>> + * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
>> + */
>> +#include <xen/errno.h>
>> +#include <xen/lib.h>
>> +#include <xen/sched.h>
>> +
>> +
>> +int hvm_acpi_domctl_access(struct domain *d, uint8_t rw,
> Wouldn't "rw" better be bool internally?

I will drop it altogether since as you pointed out below there is no
reason to keep xen_acpi_access_t as a separate structure. I'll pass
whole xen_domctl_acpi_access_t here.


(And I noticed that XEN_DOMCTL_ACPI_WRITE crept into acpi_common_*()
code in patch 5 so I will want to fix dir/rw there)

-boris

>
>> --- a/xen/include/public/domctl.h
>> +++ b/xen/include/public/domctl.h
>> @@ -1144,6 +1144,29 @@ struct xen_domctl_psr_cat_op {
>>  typedef struct xen_domctl_psr_cat_op xen_domctl_psr_cat_op_t;
>>  DEFINE_XEN_GUEST_HANDLE(xen_domctl_psr_cat_op_t);
>>  
>> +/* ACPI access structure */
>> +typedef struct xen_acpi_access {
>> +#define XEN_ACPI_SYSTEM_MEMORY 0
>> +#define XEN_ACPI_SYSTEM_IO     1
>> +    uint8_t            space_id;           /* Address space */
>> +    uint8_t            width;              /* Access size (bytes) */
>> +    uint8_t            pad[6];
>> +    uint64_aligned_t   address;            /* 64-bit address of register */
>> +} xen_acpi_access_t;
>> +
>> +struct xen_domctl_acpi_access {
>> +    xen_acpi_access_t  access;             /* IN: Register being accessed */
>> +
>> +#define XEN_DOMCTL_ACPI_READ   0
>> +#define XEN_DOMCTL_ACPI_WRITE  1
>> +    uint8_t    rw;                         /* IN: Read or write */
>> +    uint8_t    pad[7];
>> +
>> +    XEN_GUEST_HANDLE_64(void) val;         /* IN/OUT: data */
>> +};
>> +typedef struct xen_domctl_acpi_access xen_domctl_acpi_access_t;
>> +DEFINE_XEN_GUEST_HANDLE(xen_domctl_acpi_access_t);
> Do you expect to use xen_acpi_access anywhere else? If not,
> the overall amount of padding needed could be reduced by
> folding both structures.
Jan Beulich Dec. 19, 2016, 2:53 p.m. UTC | #3
>>> On 19.12.16 at 15:48, <boris.ostrovsky@oracle.com> wrote:
> On 12/19/2016 09:17 AM, Jan Beulich wrote:
>>>>> On 17.12.16 at 00:18, <boris.ostrovsky@oracle.com> wrote:
>>> --- a/xen/arch/x86/domctl.c
>>> +++ b/xen/arch/x86/domctl.c
>>> @@ -1425,6 +1425,15 @@ long arch_do_domctl(
>>>          }
>>>          break;
>>>  
>>> +    case XEN_DOMCTL_acpi_access:
>>> +        if ( !is_hvm_domain(d) )
>>> +            ret = -EINVAL;
>> I think it would be better to use some other, less frequently used
>> error code here.
> 
> ENODEV? (Because there is no ACPI "device" for PV guests)

Fine with me.

Jan
diff mbox

Patch

diff --git a/tools/flask/policy/modules/dom0.te b/tools/flask/policy/modules/dom0.te
index d0a4d91..475d446 100644
--- a/tools/flask/policy/modules/dom0.te
+++ b/tools/flask/policy/modules/dom0.te
@@ -39,7 +39,7 @@  allow dom0_t dom0_t:domain {
 };
 allow dom0_t dom0_t:domain2 {
 	set_cpuid gettsc settsc setscheduler set_max_evtchn set_vnumainfo
-	get_vnumainfo psr_cmt_op psr_cat_op
+	get_vnumainfo psr_cmt_op psr_cat_op acpi_access
 };
 allow dom0_t dom0_t:resource { add remove };
 
diff --git a/tools/flask/policy/modules/xen.if b/tools/flask/policy/modules/xen.if
index eb646f5..59e4441 100644
--- a/tools/flask/policy/modules/xen.if
+++ b/tools/flask/policy/modules/xen.if
@@ -52,7 +52,7 @@  define(`create_domain_common', `
 			settime setdomainhandle getvcpucontext };
 	allow $1 $2:domain2 { set_cpuid settsc setscheduler setclaim
 			set_max_evtchn set_vnumainfo get_vnumainfo cacheflush
-			psr_cmt_op psr_cat_op soft_reset };
+			psr_cmt_op psr_cat_op soft_reset acpi_access };
 	allow $1 $2:security check_context;
 	allow $1 $2:shadow enable;
 	allow $1 $2:mmu { map_read map_write adjust memorymap physmap pinpage mmuext_op updatemp };
@@ -85,7 +85,7 @@  define(`manage_domain', `
 			getaddrsize pause unpause trigger shutdown destroy
 			setaffinity setdomainmaxmem getscheduler resume
 			setpodtarget getpodtarget };
-    allow $1 $2:domain2 set_vnumainfo;
+    allow $1 $2:domain2 { set_vnumainfo acpi_access };
 ')
 
 # migrate_domain_out(priv, target)
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index ab9ad39..00914f6 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -1425,6 +1425,15 @@  long arch_do_domctl(
         }
         break;
 
+    case XEN_DOMCTL_acpi_access:
+        if ( !is_hvm_domain(d) )
+            ret = -EINVAL;
+        else
+            ret = hvm_acpi_domctl_access(d, domctl->u.acpi_access.rw,
+                                         &domctl->u.acpi_access.access,
+                                         domctl->u.acpi_access.val);
+        break;
+
     default:
         ret = iommu_do_domctl(domctl, d, u_domctl);
         break;
diff --git a/xen/arch/x86/hvm/Makefile b/xen/arch/x86/hvm/Makefile
index f750d13..bae3244 100644
--- a/xen/arch/x86/hvm/Makefile
+++ b/xen/arch/x86/hvm/Makefile
@@ -1,6 +1,7 @@ 
 subdir-y += svm
 subdir-y += vmx
 
+obj-y += acpi.o
 obj-y += asid.o
 obj-y += emulate.o
 obj-y += hpet.o
diff --git a/xen/arch/x86/hvm/acpi.c b/xen/arch/x86/hvm/acpi.c
new file mode 100644
index 0000000..013b399
--- /dev/null
+++ b/xen/arch/x86/hvm/acpi.c
@@ -0,0 +1,25 @@ 
+/* acpi.c: ACPI access handling
+ *
+ * Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved.
+ */
+#include <xen/errno.h>
+#include <xen/lib.h>
+#include <xen/sched.h>
+
+
+int hvm_acpi_domctl_access(struct domain *d, uint8_t rw,
+                           const xen_acpi_access_t *access,
+                           XEN_GUEST_HANDLE_PARAM(void) arg)
+{
+    return -ENOSYS;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index d55d180..32880de 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -166,6 +166,10 @@  struct hvm_domain {
 
 #define hap_enabled(d)  ((d)->arch.hvm_domain.hap_enabled)
 
+int hvm_acpi_domctl_access(struct domain *d, uint8_t rw,
+                           const xen_acpi_access_t *access,
+                           XEN_GUEST_HANDLE_PARAM(void) arg);
+
 #endif /* __ASM_X86_HVM_DOMAIN_H__ */
 
 /*
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 177319d..ba9d367 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -1144,6 +1144,29 @@  struct xen_domctl_psr_cat_op {
 typedef struct xen_domctl_psr_cat_op xen_domctl_psr_cat_op_t;
 DEFINE_XEN_GUEST_HANDLE(xen_domctl_psr_cat_op_t);
 
+/* ACPI access structure */
+typedef struct xen_acpi_access {
+#define XEN_ACPI_SYSTEM_MEMORY 0
+#define XEN_ACPI_SYSTEM_IO     1
+    uint8_t            space_id;           /* Address space */
+    uint8_t            width;              /* Access size (bytes) */
+    uint8_t            pad[6];
+    uint64_aligned_t   address;            /* 64-bit address of register */
+} xen_acpi_access_t;
+
+struct xen_domctl_acpi_access {
+    xen_acpi_access_t  access;             /* IN: Register being accessed */
+
+#define XEN_DOMCTL_ACPI_READ   0
+#define XEN_DOMCTL_ACPI_WRITE  1
+    uint8_t    rw;                         /* IN: Read or write */
+    uint8_t    pad[7];
+
+    XEN_GUEST_HANDLE_64(void) val;         /* IN/OUT: data */
+};
+typedef struct xen_domctl_acpi_access xen_domctl_acpi_access_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_acpi_access_t);
+
 struct xen_domctl {
     uint32_t cmd;
 #define XEN_DOMCTL_createdomain                   1
@@ -1221,6 +1244,7 @@  struct xen_domctl {
 #define XEN_DOMCTL_monitor_op                    77
 #define XEN_DOMCTL_psr_cat_op                    78
 #define XEN_DOMCTL_soft_reset                    79
+#define XEN_DOMCTL_acpi_access                   80
 #define XEN_DOMCTL_gdbsx_guestmemio            1000
 #define XEN_DOMCTL_gdbsx_pausevcpu             1001
 #define XEN_DOMCTL_gdbsx_unpausevcpu           1002
@@ -1283,6 +1307,7 @@  struct xen_domctl {
         struct xen_domctl_psr_cmt_op        psr_cmt_op;
         struct xen_domctl_monitor_op        monitor_op;
         struct xen_domctl_psr_cat_op        psr_cat_op;
+        struct xen_domctl_acpi_access       acpi_access;
         uint8_t                             pad[128];
     } u;
 };
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 040a251..c1ba42e 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -748,6 +748,9 @@  static int flask_domctl(struct domain *d, int cmd)
     case XEN_DOMCTL_soft_reset:
         return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SOFT_RESET);
 
+    case XEN_DOMCTL_acpi_access:
+        return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__ACPI_ACCESS);
+
     default:
         return avc_unknown_permission("domctl", cmd);
     }
diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index 92e6da9..e40258e 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -246,6 +246,8 @@  class domain2
     mem_sharing
 # XEN_DOMCTL_psr_cat_op
     psr_cat_op
+# XEN_DOMCTL_acpi_access
+    acpi_access
 }
 
 # Similar to class domain, but primarily contains domctls related to HVM domains