[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |