All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/5] CPU Hotplug v2
@ 2009-04-17 21:00 Glauber Costa
  2009-04-17 21:00 ` [Qemu-devel] [PATCH v2 1/5] split pc_new_cpu Glauber Costa
  0 siblings, 1 reply; 6+ messages in thread
From: Glauber Costa @ 2009-04-17 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori

Adressing all concerns.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH v2 1/5] split pc_new_cpu
  2009-04-17 21:00 [Qemu-devel] [PATCH v2 0/5] CPU Hotplug v2 Glauber Costa
@ 2009-04-17 21:00 ` Glauber Costa
  2009-04-17 21:00   ` [Qemu-devel] [PATCH v2 2/5] always have apic Glauber Costa
  0 siblings, 1 reply; 6+ messages in thread
From: Glauber Costa @ 2009-04-17 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori

since it is useful elsewhere.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 hw/pc.c |   37 ++++++++++++++++++++++---------------
 hw/pc.h |    1 +
 2 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 6a1750e..39ed066 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -775,6 +775,26 @@ static int load_option_rom(const char *oprom, target_phys_addr_t start,
         return size;
 }
 
+CPUState *pc_new_cpu(int cpu, const char *cpu_model, int pci_enabled)
+{
+    CPUState *env = cpu_init(cpu_model);
+    if (!env) {
+        fprintf(stderr, "Unable to find x86 CPU definition\n");
+        exit(1);
+    }
+    if (cpu != 0)
+        env->halted = 1;
+    if (smp_cpus > 1) {
+        /* XXX: enable it in all cases */
+        env->cpuid_features |= CPUID_APIC;
+    }
+    qemu_register_reset(main_cpu_reset, env);
+    if (pci_enabled) {
+        apic_init(env);
+    }
+    return env;
+}
+
 /* PC hardware initialisation */
 static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
                      const char *boot_device,
@@ -816,23 +836,10 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
     }
     
     for(i = 0; i < smp_cpus; i++) {
-        env = cpu_init(cpu_model);
-        if (!env) {
-            fprintf(stderr, "Unable to find x86 CPU definition\n");
-            exit(1);
-        }
-        if (i != 0)
-            env->halted = 1;
-        if (smp_cpus > 1) {
-            /* XXX: enable it in all cases */
-            env->cpuid_features |= CPUID_APIC;
-        }
-        qemu_register_reset(main_cpu_reset, env);
-        if (pci_enabled) {
-            apic_init(env);
-        }
+        env = pc_new_cpu(i, cpu_model, pci_enabled);
     }
 
+
     vmport_init();
 
     /* allocate RAM */
diff --git a/hw/pc.h b/hw/pc.h
index 50e6c39..59047b5 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -102,6 +102,7 @@ extern int fd_bootchk;
 
 void ioport_set_a20(int enable);
 int ioport_get_a20(void);
+CPUState *pc_new_cpu(int cpu, const char *cpu_model, int pci_enabled);
 
 /* acpi.c */
 extern int acpi_enabled;
-- 
1.5.6.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH v2 2/5] always have apic
  2009-04-17 21:00 ` [Qemu-devel] [PATCH v2 1/5] split pc_new_cpu Glauber Costa
@ 2009-04-17 21:00   ` Glauber Costa
  2009-04-17 21:00     ` [Qemu-devel] [PATCH v2 3/5] Fix warnings and errors with DEBUG enabled Glauber Costa
  0 siblings, 1 reply; 6+ messages in thread
From: Glauber Costa @ 2009-04-17 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori

if we are going to initialize the apic, set cpuid bit unconditionally.
As far as I know, we should not do that for isa machines anyway.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 hw/pc.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/hw/pc.c b/hw/pc.c
index 39ed066..7649f2c 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -784,12 +784,10 @@ CPUState *pc_new_cpu(int cpu, const char *cpu_model, int pci_enabled)
     }
     if (cpu != 0)
         env->halted = 1;
-    if (smp_cpus > 1) {
-        /* XXX: enable it in all cases */
-        env->cpuid_features |= CPUID_APIC;
-    }
+
     qemu_register_reset(main_cpu_reset, env);
     if (pci_enabled) {
+        env->cpuid_features |= CPUID_APIC;
         apic_init(env);
     }
     return env;
-- 
1.5.6.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH v2 3/5] Fix warnings and errors with DEBUG enabled
  2009-04-17 21:00   ` [Qemu-devel] [PATCH v2 2/5] always have apic Glauber Costa
@ 2009-04-17 21:00     ` Glauber Costa
  2009-04-17 21:00       ` [Qemu-devel] [PATCH v2 4/5] disallow kqemu if we fail to load it Glauber Costa
  0 siblings, 1 reply; 6+ messages in thread
From: Glauber Costa @ 2009-04-17 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori

Appearently nobody tried this yet. It produces tons
of warning and an one error.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 hw/acpi.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/hw/acpi.c b/hw/acpi.c
index 52f50a0..22fbc4a 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -604,7 +604,7 @@ static uint32_t gpe_readb(void *opaque, uint32_t addr)
     }
 
 #if defined(DEBUG)
-    printf("gpe read %lx == %lx\n", addr, val);
+    printf("gpe read %x == %x\n", addr, val);
 #endif
     return val;
 }
@@ -646,7 +646,7 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
    }
 
 #if defined(DEBUG)
-    printf("gpe write %lx <== %d\n", addr, val);
+    printf("gpe write %x <== %d\n", addr, val);
 #endif
 }
 
@@ -666,7 +666,7 @@ static uint32_t pcihotplug_read(void *opaque, uint32_t addr)
     }
 
 #if defined(DEBUG)
-    printf("pcihotplug read %lx == %lx\n", addr, val);
+    printf("pcihotplug read %x == %x\n", addr, val);
 #endif
     return val;
 }
@@ -684,14 +684,14 @@ static void pcihotplug_write(void *opaque, uint32_t addr, uint32_t val)
    }
 
 #if defined(DEBUG)
-    printf("pcihotplug write %lx <== %d\n", addr, val);
+    printf("pcihotplug write %x <== %d\n", addr, val);
 #endif
 }
 
 static uint32_t pciej_read(void *opaque, uint32_t addr)
 {
 #if defined(DEBUG)
-    printf("pciej read %lx == %lx\n", addr, val);
+    printf("pciej read %x == %x\n", addr, 0);
 #endif
     return 0;
 }
@@ -705,7 +705,7 @@ static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
 #endif
 
 #if defined(DEBUG)
-    printf("pciej write %lx <== %d\n", addr, val);
+    printf("pciej write %x <== %d\n", addr, val);
 #endif
 }
 
-- 
1.5.6.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH v2 4/5] disallow kqemu if we fail to load it.
  2009-04-17 21:00     ` [Qemu-devel] [PATCH v2 3/5] Fix warnings and errors with DEBUG enabled Glauber Costa
@ 2009-04-17 21:00       ` Glauber Costa
  2009-04-17 21:00         ` [Qemu-devel] [PATCH v2 5/5] enable cpu hotplug Glauber Costa
  0 siblings, 1 reply; 6+ messages in thread
From: Glauber Costa @ 2009-04-17 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori

Since we're not retrying it anyway, set kqemu_allowed = 0
if we fail to load it. It will allow us to test for kqemu
runtime presence where we don't have an env pointer, possibly
because we don't have a cpu yet.

The monitor code is such an example.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 kqemu.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/kqemu.c b/kqemu.c
index 040e817..e0e0499 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -179,14 +179,14 @@ int kqemu_init(CPUState *env)
     if (kqemu_fd == KQEMU_INVALID_FD) {
         fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %lu\n",
                 KQEMU_DEVICE, GetLastError());
-        return -1;
+        goto out;
     }
 #else
     kqemu_fd = open(KQEMU_DEVICE, O_RDWR);
     if (kqemu_fd == KQEMU_INVALID_FD) {
         fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %s\n",
                 KQEMU_DEVICE, strerror(errno));
-        return -1;
+        goto out;
     }
 #endif
     version = 0;
@@ -239,6 +239,8 @@ int kqemu_init(CPUState *env)
     fail:
         kqemu_closefd(kqemu_fd);
         kqemu_fd = KQEMU_INVALID_FD;
+    out:
+        kqemu_allowed = 0;
         return -1;
     }
     kqemu_update_cpuid(env);
-- 
1.5.6.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [Qemu-devel] [PATCH v2 5/5] enable cpu hotplug
  2009-04-17 21:00       ` [Qemu-devel] [PATCH v2 4/5] disallow kqemu if we fail to load it Glauber Costa
@ 2009-04-17 21:00         ` Glauber Costa
  0 siblings, 0 replies; 6+ messages in thread
From: Glauber Costa @ 2009-04-17 21:00 UTC (permalink / raw)
  To: qemu-devel; +Cc: aliguori

This patch enable cpu hotplug to happen via acpi events.
Note that all it does is generate acpi messages. It still needs
guest cooperation, in the very way as real hardware.

It is basically what we have in kvm, but in a qemuish style, with
a few improvements.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 cpu-all.h |    1 +
 exec.c    |   13 +++++++++++
 hw/acpi.c |   67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 monitor.c |   21 +++++++++++++++++++
 sysemu.h  |    1 +
 5 files changed, 103 insertions(+), 0 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index aaaa70d..a0c97f7 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -745,6 +745,7 @@ int page_check_range(target_ulong start, target_ulong len, int flags);
 
 void cpu_exec_init_all(unsigned long tb_size);
 CPUState *cpu_copy(CPUState *env);
+CPUState *qemu_get_cpu(int cpu);
 
 void cpu_dump_state(CPUState *env, FILE *f,
                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
diff --git a/exec.c b/exec.c
index 13e43d0..a7ac18f 100644
--- a/exec.c
+++ b/exec.c
@@ -538,6 +538,19 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
 }
 #endif
 
+CPUState *qemu_get_cpu(int cpu)
+{
+    CPUState *env = first_cpu;
+
+    while (env) {
+        if (env->cpu_index == cpu)
+            break;
+        env = env->next_cpu;
+    }
+
+    return env;
+}
+
 void cpu_exec_init(CPUState *env)
 {
     CPUState **penv;
diff --git a/hw/acpi.c b/hw/acpi.c
index 22fbc4a..0e58dbe 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -26,6 +26,7 @@
 #include "kvm.h"
 
 //#define DEBUG
+//#define DEBUG_CPU
 
 /* i82731AB (PIIX4) compatible power management function */
 #define PM_FREQ 3579545
@@ -563,6 +564,7 @@ void qemu_system_powerdown(void)
 #endif
 
 #define GPE_BASE 0xafe0
+#define PROC_BASE 0xaf00
 #define PCI_BASE 0xae00
 #define PCI_EJ_BASE 0xae08
 
@@ -578,6 +580,7 @@ struct pci_status {
 
 static struct gpe_regs gpe;
 static struct pci_status pci0_status;
+static uint8_t cpus_sts[32];
 
 static uint32_t gpe_read_val(uint16_t val, uint32_t addr)
 {
@@ -709,11 +712,43 @@ static void pciej_write(void *opaque, uint32_t addr, uint32_t val)
 #endif
 }
 
+static uint32_t cpuhotplug_read(void *opaque, uint32_t addr)
+{
+    if ((addr < PROC_BASE) || (addr > (PROC_BASE + 31))) {
+        /* should never happen, so return a poison */
+        return 0xabcdefab;
+    } else {
+        uint8_t *cpu_status = opaque;
+#if defined(DEBUG_CPU)
+        printf("cpuhotplug read %x == %x\n", addr, cpu_status[addr - PROC_BASE]);
+#endif
+        return cpu_status[addr - PROC_BASE];
+    }
+}
+
+static void cpuhotplug_write(void *opaque, uint32_t addr, uint32_t val)
+{
+    /* don't allow to change cpus_sts from inside a guest */
+#if defined(DEBUG_CPU)
+    printf("cpuhotplug write %x <== %d\n", addr, val);
+#endif
+}
+
 void qemu_system_hot_add_init(void)
 {
+    int i = 0, cpus = smp_cpus;
+
+    while (cpus > 0) {
+        cpus_sts[i++] = (cpus < 8) ? (1 << cpus) - 1 : 0xff;
+        cpus -= 8;
+    }
+
     register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, &gpe);
     register_ioport_read(GPE_BASE, 4, 1,  gpe_readb, &gpe);
 
+    register_ioport_write(PROC_BASE, 32, 1, cpuhotplug_write, &cpus_sts);
+    register_ioport_read(PROC_BASE, 32, 1,  cpuhotplug_read, &cpus_sts);
+
     register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, &pci0_status);
     register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, &pci0_status);
 
@@ -733,6 +768,18 @@ static void disable_device(struct pci_status *p, struct gpe_regs *g, int slot)
     p->down |= (1 << slot);
 }
 
+static void enable_processor(struct gpe_regs *g, int cpu)
+{
+    g->sts |= 4;
+    cpus_sts[cpu/8] |= (1 << (cpu%8));
+}
+
+static void disable_processor(struct gpe_regs *g, int cpu)
+{
+    g->sts |= 4;
+    cpus_sts[cpu/8] &= ~(1 << (cpu%8));
+}
+
 void qemu_system_device_hot_add(int bus, int slot, int state)
 {
     pci0_status.up = 0;
@@ -747,6 +794,26 @@ void qemu_system_device_hot_add(int bus, int slot, int state)
     }
 }
 
+void qemu_system_cpu_hot_add(int cpu, int state)
+{
+    CPUState *env;
+
+    if ((state) && !qemu_get_cpu(cpu)) {
+#ifdef DEBUG_CPU
+        printf("creatng new cpu %d\n", cpu);
+#endif
+        env = pc_new_cpu(cpu, first_cpu->cpu_model_str, 1);
+        enable_processor(&gpe, cpu);
+    } else {
+        disable_processor(&gpe, cpu);
+    }
+
+    if (gpe.en & 4) {
+        qemu_set_irq(pm_state->irq, 1);
+        qemu_set_irq(pm_state->irq, 0);
+    }
+}
+
 struct acpi_table_header
 {
     char signature [4];    /* ACPI signature (4 ASCII characters) */
diff --git a/monitor.c b/monitor.c
index e764b5d..eb55077 100644
--- a/monitor.c
+++ b/monitor.c
@@ -372,6 +372,26 @@ static void do_cpu_set(Monitor *mon, int index)
         monitor_printf(mon, "Invalid CPU index\n");
 }
 
+static void do_cpu_set_nr(Monitor *mon, int value, const char *status)
+{
+    int state;
+
+    if (kvm_enabled() || kqemu_allowed) {
+        monitor_printf(mon, "CPU hotplug not supported\n");
+        return;
+    }
+
+    if (!strcmp(status, "online")) {
+       state = 1;
+    } else if (!strcmp(status, "offline")) {
+       state = 0;
+    } else {
+        monitor_printf(mon, "invalid status: %s\n", status);
+        return;
+    }
+    qemu_system_cpu_hot_add(value, state);
+}
+
 static void do_info_jit(Monitor *mon)
 {
     dump_exec_info((FILE *)mon, monitor_fprintf);
@@ -1739,6 +1759,7 @@ static const mon_cmd_t mon_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" },
     { "acl", "sss?i?", do_acl, "<command> <aclname> [<match>] [<index>]\n",
                                "acl show vnc.username\n"
                                "acl policy vnc.username deny\n"
diff --git a/sysemu.h b/sysemu.h
index 3eab34b..b69c6f0 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -175,6 +175,7 @@ extern int drive_init(struct drive_opt *arg, int snapshot, void *machine);
 /* acpi */
 void qemu_system_hot_add_init(void);
 void qemu_system_device_hot_add(int pcibus, int slot, int state);
+void qemu_system_cpu_hot_add(int cpu, int state);
 
 /* device-hotplug */
 
-- 
1.5.6.6

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-04-17 21:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-17 21:00 [Qemu-devel] [PATCH v2 0/5] CPU Hotplug v2 Glauber Costa
2009-04-17 21:00 ` [Qemu-devel] [PATCH v2 1/5] split pc_new_cpu Glauber Costa
2009-04-17 21:00   ` [Qemu-devel] [PATCH v2 2/5] always have apic Glauber Costa
2009-04-17 21:00     ` [Qemu-devel] [PATCH v2 3/5] Fix warnings and errors with DEBUG enabled Glauber Costa
2009-04-17 21:00       ` [Qemu-devel] [PATCH v2 4/5] disallow kqemu if we fail to load it Glauber Costa
2009-04-17 21:00         ` [Qemu-devel] [PATCH v2 5/5] enable cpu hotplug Glauber Costa

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.