diff mbox

[v4,06/15] domctl: Add XEN_DOMCTL_acpi_access

Message ID 1480433602-13290-7-git-send-email-boris.ostrovsky@oracle.com (mailing list archive)
State New, archived
Headers show

Commit Message

Boris Ostrovsky Nov. 29, 2016, 3:33 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>
---
Changes in v4:
* New patch

 xen/arch/x86/domctl.c            |  9 +++++++++
 xen/arch/x86/hvm/Makefile        |  1 +
 xen/arch/x86/hvm/acpi.c          | 24 ++++++++++++++++++++++++
 xen/include/asm-x86/hvm/domain.h |  3 +++
 xen/include/public/domctl.h      | 25 +++++++++++++++++++++++++
 5 files changed, 62 insertions(+)
 create mode 100644 xen/arch/x86/hvm/acpi.c

Comments

Jan Beulich Dec. 1, 2016, 4:06 p.m. UTC | #1
>>> On 29.11.16 at 16:33, <boris.ostrovsky@oracle.com> wrote:
> --- /dev/null
> +++ b/xen/arch/x86/hvm/acpi.c
> @@ -0,0 +1,24 @@
> +/* 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, gas_t *gas,

I guess the gas pointer can be const?

> --- 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 Generic Address Structure */
> +typedef struct gas {

xen_acpi_gas

> +#define XEN_ACPI_SYSTEM_MEMORY 0
> +#define XEN_ACPI_SYSTEM_IO     1
> +    uint8_t    space_id;           /* Address space */
> +    uint8_t    bit_width;          /* Size in bits of given register */
> +    uint8_t    bit_offset;         /* Bit offset within the register */
> +    uint8_t    access_width;       /* Minimum Access size (ACPI 3.0) */
> +    uint64_t   address;            /* 64-bit address of register */

uint64_aligned_t with explicit padding added ahead of it.

And then there's the question of what uses of this will look like:
I'm not convinced we need to stick to the exact ACPI layout
here, unless you expect (or could imagine) for the tool stack to
hold GAS structures coming from elsewhere in its hands. If we
don't follow the layout as strictly, we could namely widen
bit_width (and maybe bit_offset) to allow for larger transfers
in one go. And in such a relaxed model I don't think we'd need
access_width at all as a field.

> +} gas_t;

xen_acpi_gas_t

> +
> +struct xen_domctl_acpi_access {
> +    gas_t      gas;                    /* IN: Register being accessed */
> +
> +#define XEN_DOMCTL_ACPI_READ   0
> +#define XEN_DOMCTL_ACPI_WRITE  1
> +    uint8_t    rw;                     /* IN: Read or write */
> +
> +    XEN_GUEST_HANDLE_64(uint8) val;    /* IN/OUT: data */

I'd prefer if we made this void, as there's no type associated with
the data really. And please add explicit padding again.

Jan
Boris Ostrovsky Dec. 1, 2016, 4:43 p.m. UTC | #2
On 12/01/2016 11:06 AM, Jan Beulich wrote:
>
>> +++ 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 Generic Address Structure */
>> +typedef struct gas {
> xen_acpi_gas
>
>> +#define XEN_ACPI_SYSTEM_MEMORY 0
>> +#define XEN_ACPI_SYSTEM_IO     1
>> +    uint8_t    space_id;           /* Address space */
>> +    uint8_t    bit_width;          /* Size in bits of given register */
>> +    uint8_t    bit_offset;         /* Bit offset within the register */
>> +    uint8_t    access_width;       /* Minimum Access size (ACPI 3.0) */
>> +    uint64_t   address;            /* 64-bit address of register */
> uint64_aligned_t with explicit padding added ahead of it.
>
> And then there's the question of what uses of this will look like:
> I'm not convinced we need to stick to the exact ACPI layout
> here, unless you expect (or could imagine) for the tool stack to
> hold GAS structures coming from elsewhere in its hands. If we
> don't follow the layout as strictly, we could namely widen
> bit_width (and maybe bit_offset) to allow for larger transfers
> in one go. And in such a relaxed model I don't think we'd need
> access_width at all as a field.

There is indeed no current need to use actual ACPI GAS layout but then
it's not GAS, really, and should be named something else.

-boris
Jan Beulich Dec. 2, 2016, 7:48 a.m. UTC | #3
>>> On 01.12.16 at 17:43, <boris.ostrovsky@oracle.com> wrote:
> On 12/01/2016 11:06 AM, Jan Beulich wrote:
>>
>>> +++ 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 Generic Address Structure */
>>> +typedef struct gas {
>> xen_acpi_gas
>>
>>> +#define XEN_ACPI_SYSTEM_MEMORY 0
>>> +#define XEN_ACPI_SYSTEM_IO     1
>>> +    uint8_t    space_id;           /* Address space */
>>> +    uint8_t    bit_width;          /* Size in bits of given register */
>>> +    uint8_t    bit_offset;         /* Bit offset within the register */
>>> +    uint8_t    access_width;       /* Minimum Access size (ACPI 3.0) */
>>> +    uint64_t   address;            /* 64-bit address of register */
>> uint64_aligned_t with explicit padding added ahead of it.
>>
>> And then there's the question of what uses of this will look like:
>> I'm not convinced we need to stick to the exact ACPI layout
>> here, unless you expect (or could imagine) for the tool stack to
>> hold GAS structures coming from elsewhere in its hands. If we
>> don't follow the layout as strictly, we could namely widen
>> bit_width (and maybe bit_offset) to allow for larger transfers
>> in one go. And in such a relaxed model I don't think we'd need
>> access_width at all as a field.
> 
> There is indeed no current need to use actual ACPI GAS layout but then
> it's not GAS, really, and should be named something else.

Which of course is fine by me; I had referred to that structure only
for the underlying principle of specifying how to access the data.

Jan
Boris Ostrovsky Dec. 12, 2016, 1:08 p.m. UTC | #4
On 12/02/2016 02:48 AM, Jan Beulich wrote:
>>>> On 01.12.16 at 17:43, <boris.ostrovsky@oracle.com> wrote:
>> On 12/01/2016 11:06 AM, Jan Beulich wrote:
>>>
>>>> +++ 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 Generic Address Structure */
>>>> +typedef struct gas {
>>> xen_acpi_gas
>>>
>>>> +#define XEN_ACPI_SYSTEM_MEMORY 0
>>>> +#define XEN_ACPI_SYSTEM_IO     1
>>>> +    uint8_t    space_id;           /* Address space */
>>>> +    uint8_t    bit_width;          /* Size in bits of given register */
>>>> +    uint8_t    bit_offset;         /* Bit offset within the register */
>>>> +    uint8_t    access_width;       /* Minimum Access size (ACPI 3.0) */
>>>> +    uint64_t   address;            /* 64-bit address of register */
>>> uint64_aligned_t with explicit padding added ahead of it.
>>>
>>> And then there's the question of what uses of this will look like:
>>> I'm not convinced we need to stick to the exact ACPI layout
>>> here, unless you expect (or could imagine) for the tool stack to
>>> hold GAS structures coming from elsewhere in its hands. If we
>>> don't follow the layout as strictly, we could namely widen
>>> bit_width (and maybe bit_offset) to allow for larger transfers
>>> in one go. And in such a relaxed model I don't think we'd need
>>> access_width at all as a field.
>>
>> There is indeed no current need to use actual ACPI GAS layout but then
>> it's not GAS, really, and should be named something else.
>
> Which of course is fine by me; I had referred to that structure only
> for the underlying principle of specifying how to access the data.

Are there any registers that are not byte-aligned or not whole number of 
bytes?

I am thinking about dropping bit_offset (along with access_width) and 
making bit_width (byte_)width. And keeping the latter as uint8_t will 
also implicitly limit register size to 256 bytes which I think is a 
reasonable size limit.

-boris
Julien Grall Dec. 12, 2016, 1:28 p.m. UTC | #5
Hi Boris,

On 29/11/16 15:33, Boris Ostrovsky wrote:
> 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

Can you explain why we would need this on ARM?

Cheers,

>
> Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> ---
> Changes in v4:
> * New patch
>
>  xen/arch/x86/domctl.c            |  9 +++++++++
>  xen/arch/x86/hvm/Makefile        |  1 +
>  xen/arch/x86/hvm/acpi.c          | 24 ++++++++++++++++++++++++
>  xen/include/asm-x86/hvm/domain.h |  3 +++
>  xen/include/public/domctl.h      | 25 +++++++++++++++++++++++++
>  5 files changed, 62 insertions(+)
>  create mode 100644 xen/arch/x86/hvm/acpi.c
>
> diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
> index 2a2fe04..111bcbb 100644
> --- a/xen/arch/x86/domctl.c
> +++ b/xen/arch/x86/domctl.c
> @@ -1430,6 +1430,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.gas,
> +                                         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..7d42eaf
> --- /dev/null
> +++ b/xen/arch/x86/hvm/acpi.c
> @@ -0,0 +1,24 @@
> +/* 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, gas_t *gas,
> +                           XEN_GUEST_HANDLE_PARAM(uint8) 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 d55b432..c5cd86c 100644
> --- a/xen/include/asm-x86/hvm/domain.h
> +++ b/xen/include/asm-x86/hvm/domain.h
> @@ -158,6 +158,9 @@ struct hvm_domain {
>
>  #define hap_enabled(d)  ((d)->arch.hvm_domain.hap_enabled)
>
> +int hvm_acpi_domctl_access(struct domain *currd, uint8_t rw, gas_t *gas,
> +                           XEN_GUEST_HANDLE_PARAM(uint8) arg);
> +
>  #endif /* __ASM_X86_HVM_DOMAIN_H__ */
>
>  /*
> diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
> index 177319d..26fe009 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 Generic Address Structure */
> +typedef struct gas {
> +#define XEN_ACPI_SYSTEM_MEMORY 0
> +#define XEN_ACPI_SYSTEM_IO     1
> +    uint8_t    space_id;           /* Address space */
> +    uint8_t    bit_width;          /* Size in bits of given register */
> +    uint8_t    bit_offset;         /* Bit offset within the register */
> +    uint8_t    access_width;       /* Minimum Access size (ACPI 3.0) */
> +    uint64_t   address;            /* 64-bit address of register */
> +} gas_t;
> +
> +struct xen_domctl_acpi_access {
> +    gas_t      gas;                    /* IN: Register being accessed */
> +
> +#define XEN_DOMCTL_ACPI_READ   0
> +#define XEN_DOMCTL_ACPI_WRITE  1
> +    uint8_t    rw;                     /* IN: Read or write */
> +
> +    XEN_GUEST_HANDLE_64(uint8) 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;
>  };
>
Jan Beulich Dec. 12, 2016, 2:02 p.m. UTC | #6
>>> On 12.12.16 at 14:08, <boris.ostrovsky@oracle.com> wrote:

> 
> On 12/02/2016 02:48 AM, Jan Beulich wrote:
>>>>> On 01.12.16 at 17:43, <boris.ostrovsky@oracle.com> wrote:
>>> On 12/01/2016 11:06 AM, Jan Beulich wrote:
>>>>
>>>>> +++ 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 Generic Address Structure */
>>>>> +typedef struct gas {
>>>> xen_acpi_gas
>>>>
>>>>> +#define XEN_ACPI_SYSTEM_MEMORY 0
>>>>> +#define XEN_ACPI_SYSTEM_IO     1
>>>>> +    uint8_t    space_id;           /* Address space */
>>>>> +    uint8_t    bit_width;          /* Size in bits of given register */
>>>>> +    uint8_t    bit_offset;         /* Bit offset within the register */
>>>>> +    uint8_t    access_width;       /* Minimum Access size (ACPI 3.0) */
>>>>> +    uint64_t   address;            /* 64-bit address of register */
>>>> uint64_aligned_t with explicit padding added ahead of it.
>>>>
>>>> And then there's the question of what uses of this will look like:
>>>> I'm not convinced we need to stick to the exact ACPI layout
>>>> here, unless you expect (or could imagine) for the tool stack to
>>>> hold GAS structures coming from elsewhere in its hands. If we
>>>> don't follow the layout as strictly, we could namely widen
>>>> bit_width (and maybe bit_offset) to allow for larger transfers
>>>> in one go. And in such a relaxed model I don't think we'd need
>>>> access_width at all as a field.
>>>
>>> There is indeed no current need to use actual ACPI GAS layout but then
>>> it's not GAS, really, and should be named something else.
>>
>> Which of course is fine by me; I had referred to that structure only
>> for the underlying principle of specifying how to access the data.
> 
> Are there any registers that are not byte-aligned or not whole number of 
> bytes?
> 
> I am thinking about dropping bit_offset (along with access_width) and 
> making bit_width (byte_)width. And keeping the latter as uint8_t will 
> also implicitly limit register size to 256 bytes which I think is a 
> reasonable size limit.

Since we're doing the emulation (and hence defining the registers)
we could require no such unusual registers. This would be something
we can't simplify only if we foresee ever needing to hand through a
hardware register without interposing any emulation.

Whether limiting to 256 bytes is reasonable I'm not so sure, otoh.

Jan
Boris Ostrovsky Dec. 12, 2016, 4:11 p.m. UTC | #7
On 12/12/2016 08:28 AM, Julien Grall wrote:
> Hi Boris,
>
> On 29/11/16 15:33, Boris Ostrovsky wrote:
>> 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
>
> Can you explain why we would need this on ARM?

What this is meant to say is that the new domctl is not specific to x86
and therefore is available as a common (as opposed to arch-specific)
interface.

If ARM ever needs to access ACPI space from toostack it should be able
to use it (provided that an implementation for that is available in
arch/arm).

-boris


>
> Cheers,
>
>>
>> Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com>
>> ---
>> Changes in v4:
>> * New patch
>>
>>  xen/arch/x86/domctl.c            |  9 +++++++++
>>  xen/arch/x86/hvm/Makefile        |  1 +
>>  xen/arch/x86/hvm/acpi.c          | 24 ++++++++++++++++++++++++
>>  xen/include/asm-x86/hvm/domain.h |  3 +++
>>  xen/include/public/domctl.h      | 25 +++++++++++++++++++++++++
>>  5 files changed, 62 insertions(+)
>>  create mode 100644 xen/arch/x86/hvm/acpi.c
>>
>> diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
>> index 2a2fe04..111bcbb 100644
>> --- a/xen/arch/x86/domctl.c
>> +++ b/xen/arch/x86/domctl.c
>> @@ -1430,6 +1430,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.gas,
>> +                                         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..7d42eaf
>> --- /dev/null
>> +++ b/xen/arch/x86/hvm/acpi.c
>> @@ -0,0 +1,24 @@
>> +/* 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, gas_t *gas,
>> +                           XEN_GUEST_HANDLE_PARAM(uint8) 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 d55b432..c5cd86c 100644
>> --- a/xen/include/asm-x86/hvm/domain.h
>> +++ b/xen/include/asm-x86/hvm/domain.h
>> @@ -158,6 +158,9 @@ struct hvm_domain {
>>
>>  #define hap_enabled(d)  ((d)->arch.hvm_domain.hap_enabled)
>>
>> +int hvm_acpi_domctl_access(struct domain *currd, uint8_t rw, gas_t
>> *gas,
>> +                           XEN_GUEST_HANDLE_PARAM(uint8) arg);
>> +
>>  #endif /* __ASM_X86_HVM_DOMAIN_H__ */
>>
>>  /*
>> diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
>> index 177319d..26fe009 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 Generic Address Structure */
>> +typedef struct gas {
>> +#define XEN_ACPI_SYSTEM_MEMORY 0
>> +#define XEN_ACPI_SYSTEM_IO     1
>> +    uint8_t    space_id;           /* Address space */
>> +    uint8_t    bit_width;          /* Size in bits of given register */
>> +    uint8_t    bit_offset;         /* Bit offset within the register */
>> +    uint8_t    access_width;       /* Minimum Access size (ACPI 3.0) */
>> +    uint64_t   address;            /* 64-bit address of register */
>> +} gas_t;
>> +
>> +struct xen_domctl_acpi_access {
>> +    gas_t      gas;                    /* IN: Register being
>> accessed */
>> +
>> +#define XEN_DOMCTL_ACPI_READ   0
>> +#define XEN_DOMCTL_ACPI_WRITE  1
>> +    uint8_t    rw;                     /* IN: Read or write */
>> +
>> +    XEN_GUEST_HANDLE_64(uint8) 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;
>>  };
>>
>
Boris Ostrovsky Dec. 12, 2016, 4:19 p.m. UTC | #8
On 12/12/2016 09:02 AM, Jan Beulich wrote:
>>>> On 12.12.16 at 14:08, <boris.ostrovsky@oracle.com> wrote:
>> On 12/02/2016 02:48 AM, Jan Beulich wrote:
>>>>>> On 01.12.16 at 17:43, <boris.ostrovsky@oracle.com> wrote:
>>>> On 12/01/2016 11:06 AM, Jan Beulich wrote:
>>>>>> +++ 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 Generic Address Structure */
>>>>>> +typedef struct gas {
>>>>> xen_acpi_gas
>>>>>
>>>>>> +#define XEN_ACPI_SYSTEM_MEMORY 0
>>>>>> +#define XEN_ACPI_SYSTEM_IO     1
>>>>>> +    uint8_t    space_id;           /* Address space */
>>>>>> +    uint8_t    bit_width;          /* Size in bits of given register */
>>>>>> +    uint8_t    bit_offset;         /* Bit offset within the register */
>>>>>> +    uint8_t    access_width;       /* Minimum Access size (ACPI 3.0) */
>>>>>> +    uint64_t   address;            /* 64-bit address of register */
>>>>> uint64_aligned_t with explicit padding added ahead of it.
>>>>>
>>>>> And then there's the question of what uses of this will look like:
>>>>> I'm not convinced we need to stick to the exact ACPI layout
>>>>> here, unless you expect (or could imagine) for the tool stack to
>>>>> hold GAS structures coming from elsewhere in its hands. If we
>>>>> don't follow the layout as strictly, we could namely widen
>>>>> bit_width (and maybe bit_offset) to allow for larger transfers
>>>>> in one go. And in such a relaxed model I don't think we'd need
>>>>> access_width at all as a field.
>>>> There is indeed no current need to use actual ACPI GAS layout but then
>>>> it's not GAS, really, and should be named something else.
>>> Which of course is fine by me; I had referred to that structure only
>>> for the underlying principle of specifying how to access the data.
>> Are there any registers that are not byte-aligned or not whole number of 
>> bytes?
>>
>> I am thinking about dropping bit_offset (along with access_width) and 
>> making bit_width (byte_)width. And keeping the latter as uint8_t will 
>> also implicitly limit register size to 256 bytes which I think is a 
>> reasonable size limit.
> Since we're doing the emulation (and hence defining the registers)
> we could require no such unusual registers. This would be something
> we can't simplify only if we foresee ever needing to hand through a
> hardware register without interposing any emulation.
>
> Whether limiting to 256 bytes is reasonable I'm not so sure, otoh.

When would we ever need to access anything larger? I'd think that the
common case is a few (1-4) bytes. The one instance when this is not true
is the VCPU map and 256 bytes allow for 16K VCPUs, which I suspect we
won't reach in a while.

But I can increase the length to uint16_t if you feel it's would be better.

-boris
Jan Beulich Dec. 12, 2016, 4:24 p.m. UTC | #9
>>> On 12.12.16 at 17:19, <boris.ostrovsky@oracle.com> wrote:
> On 12/12/2016 09:02 AM, Jan Beulich wrote:
>>>>> On 12.12.16 at 14:08, <boris.ostrovsky@oracle.com> wrote:
>>> On 12/02/2016 02:48 AM, Jan Beulich wrote:
>>>>>>> On 01.12.16 at 17:43, <boris.ostrovsky@oracle.com> wrote:
>>>>> On 12/01/2016 11:06 AM, Jan Beulich wrote:
>>>>>>> +++ 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 Generic Address Structure */
>>>>>>> +typedef struct gas {
>>>>>> xen_acpi_gas
>>>>>>
>>>>>>> +#define XEN_ACPI_SYSTEM_MEMORY 0
>>>>>>> +#define XEN_ACPI_SYSTEM_IO     1
>>>>>>> +    uint8_t    space_id;           /* Address space */
>>>>>>> +    uint8_t    bit_width;          /* Size in bits of given register */
>>>>>>> +    uint8_t    bit_offset;         /* Bit offset within the register */
>>>>>>> +    uint8_t    access_width;       /* Minimum Access size (ACPI 3.0) */
>>>>>>> +    uint64_t   address;            /* 64-bit address of register */
>>>>>> uint64_aligned_t with explicit padding added ahead of it.
>>>>>>
>>>>>> And then there's the question of what uses of this will look like:
>>>>>> I'm not convinced we need to stick to the exact ACPI layout
>>>>>> here, unless you expect (or could imagine) for the tool stack to
>>>>>> hold GAS structures coming from elsewhere in its hands. If we
>>>>>> don't follow the layout as strictly, we could namely widen
>>>>>> bit_width (and maybe bit_offset) to allow for larger transfers
>>>>>> in one go. And in such a relaxed model I don't think we'd need
>>>>>> access_width at all as a field.
>>>>> There is indeed no current need to use actual ACPI GAS layout but then
>>>>> it's not GAS, really, and should be named something else.
>>>> Which of course is fine by me; I had referred to that structure only
>>>> for the underlying principle of specifying how to access the data.
>>> Are there any registers that are not byte-aligned or not whole number of 
>>> bytes?
>>>
>>> I am thinking about dropping bit_offset (along with access_width) and 
>>> making bit_width (byte_)width. And keeping the latter as uint8_t will 
>>> also implicitly limit register size to 256 bytes which I think is a 
>>> reasonable size limit.
>> Since we're doing the emulation (and hence defining the registers)
>> we could require no such unusual registers. This would be something
>> we can't simplify only if we foresee ever needing to hand through a
>> hardware register without interposing any emulation.
>>
>> Whether limiting to 256 bytes is reasonable I'm not so sure, otoh.
> 
> When would we ever need to access anything larger? I'd think that the
> common case is a few (1-4) bytes. The one instance when this is not true
> is the VCPU map and 256 bytes allow for 16K VCPUs, which I suspect we
> won't reach in a while.
> 
> But I can increase the length to uint16_t if you feel it's would be better.

It's domctl, so we can change it later anyway. As said - I'm not
really sure here.

Jan
Julien Grall Dec. 13, 2016, 1:02 p.m. UTC | #10
Hi Boris,

On 12/12/16 16:11, Boris Ostrovsky wrote:
> On 12/12/2016 08:28 AM, Julien Grall wrote:
>> Hi Boris,
>>
>> On 29/11/16 15:33, Boris Ostrovsky wrote:
>>> 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
>>
>> Can you explain why we would need this on ARM?
>
> What this is meant to say is that the new domctl is not specific to x86
> and therefore is available as a common (as opposed to arch-specific)
> interface.

I thought you were planning to make this implemented on ARM and was 
trying to understanding why :).

>
> If ARM ever needs to access ACPI space from toostack it should be able
> to use it (provided that an implementation for that is available in
> arch/arm).

Ok. I can't tell whether we would need it in the future. Currently, it 
is not necessary.

Cheers,
diff mbox

Patch

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 2a2fe04..111bcbb 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -1430,6 +1430,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.gas,
+                                         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..7d42eaf
--- /dev/null
+++ b/xen/arch/x86/hvm/acpi.c
@@ -0,0 +1,24 @@ 
+/* 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, gas_t *gas,
+                           XEN_GUEST_HANDLE_PARAM(uint8) 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 d55b432..c5cd86c 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -158,6 +158,9 @@  struct hvm_domain {
 
 #define hap_enabled(d)  ((d)->arch.hvm_domain.hap_enabled)
 
+int hvm_acpi_domctl_access(struct domain *currd, uint8_t rw, gas_t *gas,
+                           XEN_GUEST_HANDLE_PARAM(uint8) arg);
+
 #endif /* __ASM_X86_HVM_DOMAIN_H__ */
 
 /*
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 177319d..26fe009 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 Generic Address Structure */
+typedef struct gas {
+#define XEN_ACPI_SYSTEM_MEMORY 0
+#define XEN_ACPI_SYSTEM_IO     1
+    uint8_t    space_id;           /* Address space */
+    uint8_t    bit_width;          /* Size in bits of given register */
+    uint8_t    bit_offset;         /* Bit offset within the register */
+    uint8_t    access_width;       /* Minimum Access size (ACPI 3.0) */
+    uint64_t   address;            /* 64-bit address of register */
+} gas_t;
+
+struct xen_domctl_acpi_access {
+    gas_t      gas;                    /* IN: Register being accessed */
+
+#define XEN_DOMCTL_ACPI_READ   0
+#define XEN_DOMCTL_ACPI_WRITE  1
+    uint8_t    rw;                     /* IN: Read or write */
+
+    XEN_GUEST_HANDLE_64(uint8) 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;
 };