[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [qemu-xen-unstable] HVM vcpu add/remove: qemu logic for vcpu add/revmoe



commit 12d0187099adeb242eb7c232a0f3bf9d153716c3
Author: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
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@xxxxxxxxx>
    
    [ 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@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.