@@ -2710,6 +2710,26 @@ int xc_livepatch_revert(xc_interface *xch, char *name, uint32_t timeout);
int xc_livepatch_unload(xc_interface *xch, char *name, uint32_t timeout);
int xc_livepatch_replace(xc_interface *xch, char *name, uint32_t timeout);
+int xc_acpi_access(xc_interface *xch, domid_t domid,
+ uint8_t rw, uint8_t space_id, unsigned long addr,
+ unsigned int bytes, void *val);
+
+static inline int xc_acpi_ioread(xc_interface *xch, domid_t domid,
+ unsigned long port,
+ unsigned int bytes, void *val)
+{
+ return xc_acpi_access(xch, domid, XEN_DOMCTL_ACPI_READ, XEN_ACPI_SYSTEM_IO,
+ port, bytes, val);
+}
+
+static inline int xc_acpi_iowrite(xc_interface *xch, domid_t domid,
+ unsigned long port,
+ unsigned int bytes, void *val)
+{
+ return xc_acpi_access(xch, domid, XEN_DOMCTL_ACPI_WRITE, XEN_ACPI_SYSTEM_IO,
+ port, bytes, val);
+}
+
/* Compat shims */
#include "xenctrl_compat.h"
@@ -2520,6 +2520,43 @@ int xc_domain_soft_reset(xc_interface *xch,
domctl.domain = (domid_t)domid;
return do_domctl(xch, &domctl);
}
+
+int
+xc_acpi_access(xc_interface *xch, domid_t domid,
+ uint8_t rw, uint8_t space_id,
+ unsigned long address, unsigned int bytes, void *val)
+{
+ DECLARE_DOMCTL;
+ DECLARE_HYPERCALL_BOUNCE(val, bytes, XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
+ struct xen_acpi_access *access = &domctl.u.acpi_access.access;
+ unsigned max_bytes = (1U << (sizeof(access->width) * 8)) - 1;
+
+ while ( bytes != 0 )
+ {
+ if ( xc_hypercall_bounce_pre(xch, val) )
+ return -1;
+
+ memset(&domctl, 0, sizeof(domctl));
+ domctl.domain = domid;
+ domctl.cmd = XEN_DOMCTL_acpi_access;
+ access->space_id = space_id;
+ access->width = bytes < max_bytes ? bytes : max_bytes;
+ access->address = address;
+ domctl.u.acpi_access.rw = rw;
+ set_xen_guest_handle(domctl.u.acpi_access.val, val);
+
+ if ( do_domctl(xch, &domctl) != 0 )
+ return -1;
+
+ xc_hypercall_bounce_post(xch, val);
+
+ bytes -= access->width;
+ address += access->width;
+ }
+
+ return 0;
+}
+
/*
* Local variables:
* mode: C
@@ -5147,7 +5147,11 @@ int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid, libxl_bitmap *cpumap)
case LIBXL_DOMAIN_TYPE_HVM:
switch (libxl__device_model_version_running(gc, domid)) {
case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL:
+ break;
case LIBXL_DEVICE_MODEL_VERSION_NONE:
+ rc = libxl__arch_set_vcpuonline(gc, domid, cpumap);
+ if (rc < 0)
+ LOGE(ERROR, "Can't change vcpu online map (%d)", rc);
break;
case LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN:
rc = libxl__set_vcpuonline_qmp(gc, domid, cpumap, &info);
@@ -71,6 +71,10 @@ int libxl__arch_extra_memory(libxl__gc *gc,
const libxl_domain_build_info *info,
uint64_t *out);
+_hidden
+int libxl__arch_set_vcpuonline(libxl__gc *gc, uint32_t domid,
+ libxl_bitmap *cpumap);
+
#if defined(__i386__) || defined(__x86_64__)
#define LAPIC_BASE_ADDRESS 0xfee00000
@@ -126,6 +126,12 @@ out:
return rc;
}
+int libxl__arch_set_vcpuonline(libxl__gc *gc, uint32_t domid,
+ libxl_bitmap *cpumap)
+{
+ return ERROR_FAIL;
+}
+
static struct arch_info {
const char *guest_type;
const char *timer_compat;
@@ -309,6 +309,16 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
return ERROR_FAIL;
}
+ if ((info->type == LIBXL_DOMAIN_TYPE_HVM) &&
+ (libxl__device_model_version_running(gc, domid) ==
+ LIBXL_DEVICE_MODEL_VERSION_NONE)) {
+ rc = libxl__arch_set_vcpuonline(gc, domid, &info->avail_vcpus);
+ if (rc) {
+ LOG(ERROR, "Couldn't set available vcpu count (error %d)", rc);
+ return ERROR_FAIL;
+ }
+ }
+
/*
* Check if the domain has any CPU or node affinity already. If not, try
* to build up the latter via automatic NUMA placement. In fact, in case
@@ -3,6 +3,9 @@
#include <xc_dom.h>
+#include <xen/arch-x86/xen.h>
+#include <xen/hvm/ioreq.h>
+
int libxl__arch_domain_prepare_config(libxl__gc *gc,
libxl_domain_config *d_config,
xc_domain_configuration_t *xc_config)
@@ -368,6 +371,24 @@ int libxl__arch_extra_memory(libxl__gc *gc,
return 0;
}
+int libxl__arch_set_vcpuonline(libxl__gc *gc, uint32_t domid,
+ libxl_bitmap *cpumap)
+{
+ int rc;
+
+ /*Update VCPU map. */
+ rc = xc_acpi_iowrite(CTX->xch, domid, XEN_ACPI_CPU_MAP,
+ cpumap->size, cpumap->map);
+ if (!rc) {
+ /* Send an SCI. */
+ uint16_t val = 1 << XEN_ACPI_GPE0_CPUHP_BIT;
+ rc = xc_acpi_iowrite(CTX->xch, domid, ACPI_GPE0_BLK_ADDRESS_V1,
+ sizeof(val), &val);
+ }
+
+ return rc;
+}
+
int libxl__arch_domain_init_hw_description(libxl__gc *gc,
libxl_domain_build_info *info,
libxl__domain_build_state *state,
Provide libxc interface for accessing ACPI via XEN_DOMCTL_acpi_access. When a VCPU is hot-(un)plugged to/from a PVH guest update VCPU map by writing to ACPI's XEN_ACPI_CPU_MAP register and then set GPE0 status bit in GPE0.status. Signed-off-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> --- Changes in v5: * xc_acpi_access() changes due to new interface structure * Set VCPU online map during domain creation (in libxl__build_pre()) tools/libxc/include/xenctrl.h | 20 ++++++++++++++++++++ tools/libxc/xc_domain.c | 37 +++++++++++++++++++++++++++++++++++++ tools/libxl/libxl.c | 4 ++++ tools/libxl/libxl_arch.h | 4 ++++ tools/libxl/libxl_arm.c | 6 ++++++ tools/libxl/libxl_dom.c | 10 ++++++++++ tools/libxl/libxl_x86.c | 21 +++++++++++++++++++++ 7 files changed, 102 insertions(+)