Mailing List Archive

[qemu-xen-unstable] HVM vcpu add/remove: qemu logic for vcpu add/revmoe
commit 12d0187099adeb242eb7c232a0f3bf9d153716c3
Author: Ian Jackson <ian.jackson@eu.citrix.com>
Date: Mon Jan 4 17:12:44 2010 +0000

HVM vcpu add/remove: qemu logic for vcpu add/revmoe

-- at qemu side, get vcpu_avail which used for original cpu avail map;
-- setup gpe ioread/iowrite at qmeu;
-- setup vcpu add/remove user interface through monitor;
-- setup SCI logic;

Signed-off-by: Liu, Jinsong <jinsong.liu@intel.com>

[ PATCH 4/4 ] HVM vcpu add/remove: qemu logic for vcpu add/revmoe
---
hw/piix4acpi.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++
i386-dm/helper2.c | 1 +
monitor.c | 18 +++++++++++++
sysemu.h | 1 +
vl.c | 7 +++++
xen-config-host.h | 1 +
6 files changed, 102 insertions(+), 0 deletions(-)

diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c
index 599d00d..ccbdf84 100644
--- a/hw/piix4acpi.c
+++ b/hw/piix4acpi.c
@@ -69,6 +69,9 @@
#define DEVFN_TO_PHP_SLOT_REG(devfn) (devfn >> 1)
#define PHP_SLOT_REG_TO_DEVFN(reg, hilo) ((reg << 1) | hilo)

+/* ioport to monitor cpu add/remove status */
+#define PROC_BASE 0xaf00
+
typedef struct PCIAcpiState {
PCIDevice dev;
uint16_t pm1_control; /* pm1a_ECNT_BLK */
@@ -79,6 +82,9 @@ typedef struct GPEState {
uint8_t gpe0_sts[ACPI_GPE0_BLK_LEN / 2];
uint8_t gpe0_en[ACPI_GPE0_BLK_LEN / 2];

+ /* CPU bitmap */
+ uint8_t cpus_sts[32];
+
/* SCI IRQ level */
uint8_t sci_asserted;

@@ -480,10 +486,48 @@ static int gpe_load(QEMUFile* f, void* opaque, int version_id)
return 0;
}

+static uint32_t gpe_cpus_readb(void *opaque, uint32_t addr)
+{
+ uint32_t val = 0;
+ GPEState *g = opaque;
+
+ switch (addr) {
+ case PROC_BASE ... PROC_BASE+31:
+ val = g->cpus_sts[addr - PROC_BASE];
+ default:
+ break;
+ }
+
+ return val;
+}
+
+static void gpe_cpus_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+ GPEState *g = opaque;
+ switch (addr) {
+ case PROC_BASE ... PROC_BASE + 31:
+ /* don't allow to change cpus_sts from inside a guest */
+ break;
+ default:
+ break;
+ }
+}
+
static void gpe_acpi_init(void)
{
GPEState *s = &gpe_state;
memset(s, 0, sizeof(GPEState));
+ int i = 0, cpus = vcpus;
+ char *vcpumap = (char *)&vcpu_avail;
+
+ while (cpus > 0) {
+ s->cpus_sts[i] = vcpumap[i];
+ i++;
+ cpus -= 8;
+ }
+
+ register_ioport_read(PROC_BASE, 32, 1, gpe_cpus_readb, s);
+ register_ioport_write(PROC_BASE, 32, 1, gpe_cpus_writeb, s);

register_ioport_read(ACPI_GPE0_BLK_ADDRESS,
ACPI_GPE0_BLK_LEN / 2,
@@ -682,3 +726,33 @@ void qemu_system_device_hot_add(int bus, int devfn, int state) {
void i440fx_init_memory_mappings(PCIDevice *d) {
/* our implementation doesn't need this */
}
+
+static void enable_processor(GPEState *g, int cpu)
+{
+ g->gpe0_sts[0] |= 4;
+ g->cpus_sts[cpu/8] |= (1 << (cpu%8));
+}
+
+static void disable_processor(GPEState *g, int cpu)
+{
+ g->gpe0_sts[0] |= 4;
+ g->cpus_sts[cpu/8] &= ~(1 << (cpu%8));
+}
+
+void qemu_cpu_add_remove(int cpu, int state)
+{
+ if ((cpu <=0) || (cpu >= vcpus)) {
+ fprintf(stderr, "vcpu out of range, should be [1~%d]\n", vcpus - 1);
+ return;
+ }
+
+ if (state)
+ enable_processor(&gpe_state, cpu);
+ else
+ disable_processor(&gpe_state, cpu);
+
+ if (gpe_state.gpe0_en[0] & 4) {
+ qemu_set_irq(sci_irq, 1);
+ qemu_set_irq(sci_irq, 0);
+ }
+}
diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c
index 7fe03b0..090202b 100644
--- a/i386-dm/helper2.c
+++ b/i386-dm/helper2.c
@@ -78,6 +78,7 @@ _syscall3(int, modify_ldt, int, func, void *, ptr, unsigned long, bytecount)

int domid = -1;
int vcpus = 1;
+uint64_t vcpu_avail = 1;

int xc_handle = -1;

diff --git a/monitor.c b/monitor.c
index c8fcab7..8915a6e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1473,6 +1473,22 @@ static void do_info_balloon(void)
term_printf("balloon: actual=%d\n", (int)(actual >> 20));
}

+static void do_cpu_set_nr(int value, const char *status)
+{
+ int state;
+
+ if (!strcmp(status, "online"))
+ state = 1;
+ else if (!strcmp(status, "offline"))
+ state = 0;
+ else {
+ term_printf("invalid status: %s\n", status);
+ return;
+ }
+
+ qemu_cpu_add_remove(value, state);
+}
+
/* Please update qemu-doc.texi when adding or changing commands */
static const term_cmd_t term_cmds[] = {
{ "help|?", "s?", do_help,
@@ -1583,6 +1599,8 @@ static const term_cmd_t term_cmds[] = {
"target", "request VM to change it's memory allocation (in MB)" },
{ "set_link", "ss", do_set_link,
"name [up|down]", "change the link status of a network adapter" },
+ { "cpu_set", "is", do_cpu_set_nr,
+ "cpu [online|offline]", "change cpu state" },
{ NULL, NULL, },
};

diff --git a/sysemu.h b/sysemu.h
index d4e7514..87b278b 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -173,6 +173,7 @@ extern int drive_add(const char *file, const char *fmt, ...);
extern int drive_init(struct drive_opt *arg, int snapshot, void *machine);

/* acpi */
+void qemu_cpu_add_remove(int cpu, int state);
void qemu_system_hot_add_init(void);
void qemu_system_device_hot_add(int pcibus, int slot, int state);

diff --git a/vl.c b/vl.c
index ce57405..cb31e5a 100644
--- a/vl.c
+++ b/vl.c
@@ -4279,6 +4279,7 @@ enum {
QEMU_OPTION_domainname,
QEMU_OPTION_acpi,
QEMU_OPTION_vcpus,
+ QEMU_OPTION_vcpu_avail,

/* Debug/Expert options: */
QEMU_OPTION_serial,
@@ -4453,6 +4454,7 @@ static const QEMUOption qemu_options[] = {
{ "pciemulation", HAS_ARG, QEMU_OPTION_pci_emulation },
{ "vncunused", 0, QEMU_OPTION_vncunused },
{ "vcpus", HAS_ARG, QEMU_OPTION_vcpus },
+ { "vcpu_avail", HAS_ARG, QEMU_OPTION_vcpu_avail },
#if defined(CONFIG_XEN) && !defined(CONFIG_DM)
{ "xen-domid", HAS_ARG, QEMU_OPTION_xen_domid },
{ "xen-create", 0, QEMU_OPTION_xen_create },
@@ -5298,6 +5300,11 @@ int main(int argc, char **argv, char **envp)
vcpus = atoi(optarg);
fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
break;
+ case QEMU_OPTION_vcpu_avail:
+ vcpu_avail = atol(optarg);
+ fprintf(logfile, "qemu: the avail cpu bitmap is %lx\n",
+ vcpu_avail);
+ break;
case QEMU_OPTION_acpi:
acpi_enabled = 1;
break;
diff --git a/xen-config-host.h b/xen-config-host.h
index 3a04df9..e3f546a 100644
--- a/xen-config-host.h
+++ b/xen-config-host.h
@@ -31,6 +31,7 @@ void main_loop_prepare(void);
extern int xc_handle;
extern int xen_pause_requested;
extern int vcpus;
+extern uint64_t vcpu_avail;

#ifdef CONFIG_STUBDOM
#define bdrv_host_device bdrv_raw
--
generated by git-patchbot for /home/xen/git/qemu-xen-unstable.git

_______________________________________________
Xen-changelog mailing list
Xen-changelog@lists.xensource.com
http://lists.xensource.com/xen-changelog