When it's more close to inclusion, I'd also post it to main qemu list. But right now, I'm just aiming at a first round around this draft.

The attached patch is enough to make the notifications DEVICE_CHECK and EJECT reach the kernel. As far as I understand, some userspace black magic that keeps changing its scroll is needed to really put the processors logically off/on after the notify (acpi code itself will never call cpu_up/down)

Just let me tell you what you think.
>From c45432c0cec8241dbcd6ed6cf38c953b17a6f826 Mon Sep 17 00:00:00 2001
From: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
Date: Wed, 16 Jan 2008 18:43:11 -0200
Subject: [PATCH] RFC: qemu cpu hotplug

Signed-off-by: Glauber de Oliveira Costa <[EMAIL PROTECTED]>
---
 bios/acpi-dsdt.dsl    |   87 +++++++++++++++++++++++++++++-----
 bios/rombios32.c      |    2 +
 qemu/hw/acpi.c        |  125 +++++++++++++++++++++++++++++++++++++++++++++++++
 qemu/hw/pc.c          |    4 +-
 qemu/monitor.c        |    9 ++++
 qemu/pc-bios/bios.bin |  Bin
 6 files changed, 214 insertions(+), 13 deletions(-)

diff --git a/bios/acpi-dsdt.dsl b/bios/acpi-dsdt.dsl
index df255ce..497b866 100755
--- a/bios/acpi-dsdt.dsl
+++ b/bios/acpi-dsdt.dsl
@@ -27,18 +27,35 @@ DefinitionBlock (
 {
     Scope (_PR)
     {
-        Processor (CPU0, 0x00, 0x0000b010, 0x06) {}
-        Processor (CPU1, 0x01, 0x0000b010, 0x06) {}
-        Processor (CPU2, 0x02, 0x0000b010, 0x06) {}
-        Processor (CPU3, 0x03, 0x0000b010, 0x06) {}
-        Processor (CPU4, 0x04, 0x0000b010, 0x06) {}
-        Processor (CPU5, 0x05, 0x0000b010, 0x06) {}
-        Processor (CPU6, 0x06, 0x0000b010, 0x06) {}
-        Processor (CPU7, 0x07, 0x0000b010, 0x06) {}
-        Processor (CPU8, 0x08, 0x0000b010, 0x06) {}
-        Processor (CPU9, 0x09, 0x0000b010, 0x06) {}
-        Processor (CPUA, 0x0a, 0x0000b010, 0x06) {}
-        Processor (CPUB, 0x0b, 0x0000b010, 0x06) {}
+	OperationRegion( PRO, SystemIO, 0xaf00, 0x02)
+	Field (PRO, ByteAcc, NoLock, WriteAsZeros)
+	{
+		PR0U, 1,
+		PR1U, 1,
+		PR2U, 1,
+		PR3U, 1,
+		PR4U, 1,
+		PADU, 3,
+
+		PR0D, 1,
+		PR1D, 1,
+		PR2D, 1,
+		PR3D, 1,
+		PR4D, 1,
+		PADD, 3,
+	}
+        Processor (CPU0, 0x00, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} }
+        Processor (CPU1, 0x01, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} }
+        Processor (CPU2, 0x02, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} }
+        Processor (CPU3, 0x03, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} }
+        Processor (CPU4, 0x04, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} } 
+        Processor (CPU5, 0x05, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} }
+        Processor (CPU6, 0x06, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} }
+        Processor (CPU7, 0x07, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} }
+        Processor (CPU8, 0x08, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} }
+        Processor (CPU9, 0x09, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} }
+        Processor (CPUA, 0x0a, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} }
+        Processor (CPUB, 0x0b, 0x0000b010, 0x06) { Method (_STA) { Return(0x1)} }
         Processor (CPUC, 0x0c, 0x0000b010, 0x06) {}
         Processor (CPUD, 0x0d, 0x0000b010, 0x06) {}
         Processor (CPUE, 0x0e, 0x0000b010, 0x06) {}
@@ -559,6 +576,51 @@ DefinitionBlock (
                 }
         }
     }
+    Scope(\_GPE)
+    {
+       Method(_L00) {  
+	  Return(0x01)
+       }
+       Method(_L01) { 
+         If (\_PR.PR1U) {
+	  Notify(\_PR.CPU1, 1)
+	 }
+	 If (\_PR.PR1D){
+	  Notify(\_PR.CPU1, 3) 
+	 }
+	 Return(0x01)
+       }
+
+       Method(_L02) { 
+         If (\_PR.PR2U) {
+	  Notify(\_PR.CPU2, 1)
+	 }
+	 If (\_PR.PR2D){
+	  Notify(\_PR.CPU2, 3) 
+	 }
+	 Return(0x01)
+       }
+
+       Method(_L03) { 
+         If (\_PR.PR3U) {
+	  Notify(\_PR.CPU3, 1)
+	 }
+	 If (\_PR.PR3D){
+	  Notify(\_PR.CPU3, 3) 
+	 }
+	 Return(0x01)
+       }
+
+       Method(_L04) { 
+         If (\_PR.PR4U) {
+	  Notify(\_PR.CPU4, 1)
+	 }
+	 IF (\_PR.PR4D) {
+	  Notify(\_PR.CPU4, 3) 
+	 }
+	 Return(0x01)
+       }
+    }
 
     /* S5 = power off state */
     Name (_S5, Package (4) {
@@ -567,4 +629,5 @@ DefinitionBlock (
         0x00, // reserved
         0x00, // reserved
     })
+
 }
diff --git a/bios/rombios32.c b/bios/rombios32.c
index 967c119..4580462 100755
--- a/bios/rombios32.c
+++ b/bios/rombios32.c
@@ -1329,6 +1329,8 @@ void acpi_bios_init(void)
     fadt->pm_tmr_len = 4;
     fadt->plvl2_lat = cpu_to_le16(0x0fff); // C2 state not supported
     fadt->plvl3_lat = cpu_to_le16(0x0fff); // C3 state not supported
+    fadt->gpe0_blk = cpu_to_le32(0xafe0);
+    fadt->gpe0_blk_len = 4;
     /* WBINVD + PROC_C1 + SLP_BUTTON + FIX_RTC */
     fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 6));
     acpi_build_table_header((struct acpi_table_header *)fadt, "FACP", 
diff --git a/qemu/hw/acpi.c b/qemu/hw/acpi.c
index b97b37d..6e1af9e 100644
--- a/qemu/hw/acpi.c
+++ b/qemu/hw/acpi.c
@@ -530,3 +530,128 @@ void qemu_system_powerdown(void)
     }
 }
 #endif
+
+struct gpe_things {
+	uint16_t sts;	
+	uint16_t en;	
+	uint8_t pru;
+	uint8_t prd;
+};
+
+static struct gpe_things gpe;
+unsigned long gpe_base = 0xafe0;
+
+static uint32_t gpe_readb(void *opaque, uint32_t addr)
+{
+	struct gpe_things *g = opaque;
+	uint32_t val;
+
+	switch (addr) {
+		case 0xaf00:
+			val =  g->pru;		
+			break;
+		case 0xaf01:
+			val =  g->prd;		
+			break;
+		case 0xafe0:
+			val =  g->sts & 0xFF;
+			break;
+		case 0xafe1:
+			val =  (g->sts >> 8) & 0xFF;
+			break;
+		case 0xafe0 + 2:
+			val =  g->en & 0xFF;
+			break;
+		case 0xafe3:
+			val =  (g->en >> 8) & 0xFF;
+			break;
+		default:
+			break;
+	}
+	printf("gpe read %lx == %lx\n", addr, val);
+	return val;
+
+}
+
+static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+	struct gpe_things *g = opaque;
+
+	switch (addr) {
+		case 0xaf00:
+			break;
+		case 0xafe0:
+			g->sts = (g->sts & ~0xFFFF) | (val & 0xFFFF);
+			break;
+		case 0xafe1:
+			g->sts = (g->sts & 0xFFFF) | (val << 8);
+			break;
+		case 0xafe0 + 2:
+			g->en =  (g->en & ~0xFFFF) | (val & 0xFFFF);
+			break;
+		case 0xafe3:
+			g->en =  (g->en & 0xFFFF) | (val << 8);
+			break;
+
+		default:
+			break;
+	}
+
+	printf("gpe write %lx <== %d\n", addr, val);
+}
+
+int current_cpus = 0;
+void qemu_system_hot_add_init(void)
+{
+	int i;
+	for (i = 0; i < smp_cpus; i++)
+		gpe.pru |= (1 << i);
+
+	current_cpus = smp_cpus;
+
+	register_ioport_write(gpe_base, 4, 1, gpe_writeb, &gpe);
+	register_ioport_read(gpe_base, 4, 1,  gpe_readb, &gpe);
+
+	register_ioport_write(0xaf00, 4, 1, gpe_writeb, &gpe);
+	register_ioport_read(0xaf00, 4, 1,  gpe_readb, &gpe);
+}
+
+static void enable_processor(struct gpe_things *g, int cpu)
+{
+	g->sts |= (1 << cpu);
+	g->en |= (1 << cpu);
+	g->pru |= (1 << cpu);
+	g->prd &= ~(1 << cpu);
+}
+
+static void disable_processor(struct gpe_things *g, int cpu)
+{
+	g->sts |= (1 << cpu);
+	g->en |= (1 << cpu);
+	g->pru &= ~(1 << cpu);
+	g->prd |= (1 << cpu);
+}
+
+void qemu_system_cpu_hot_add(int cpus)
+{
+    int i;
+
+    gpe.sts = 0;
+    gpe.en = 0;
+    gpe.pru = 0;
+    gpe.prd = 0;
+
+    qemu_set_irq(pm_state->dev.irq[0], 1);
+
+    for (i = current_cpus ; i < cpus; i++) {
+	enable_processor(&gpe, i);
+	printf("proc %i up (%d %d)\n", i, gpe.sts, gpe.en);
+    }	
+    for (i = current_cpus - 1 ; i >= cpus; i--) {
+	disable_processor(&gpe, i);
+	printf("proc %i down (%d %d)\n", i, gpe.sts, gpe.en);
+    }	
+
+    qemu_set_irq(pm_state->dev.irq[0], 0);
+
+}
diff --git a/qemu/hw/pc.c b/qemu/hw/pc.c
index 3972ab4..5ce28ab 100644
--- a/qemu/hw/pc.c
+++ b/qemu/hw/pc.c
@@ -1029,7 +1029,9 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
         }
     }
 
-#define USE_HYPERCALL
+    qemu_system_hot_add_init();
+
+#undef USE_HYPERCALL
 #ifdef USE_HYPERCALL
     pci_hypercall_init(pci_bus);
 #endif
diff --git a/qemu/monitor.c b/qemu/monitor.c
index e03c473..effb696 100644
--- a/qemu/monitor.c
+++ b/qemu/monitor.c
@@ -346,6 +346,14 @@ static void do_cpu_set(int index)
         term_printf("Invalid CPU index\n");
 }
 
+static void do_cpu_set_nr(int value)
+{
+    if ((value < 1) || (value > 32)) /* second condition is possibly bogus. OS dependant */
+       term_printf("value out of range\n");
+    qemu_system_cpu_hot_add(value);
+
+}
+
 static void do_info_jit(void)
 {
     dump_exec_info(NULL, monitor_fprintf);
@@ -1339,6 +1347,7 @@ static term_cmd_t term_cmds[] = {
       "", "cancel the current VM migration" },
     { "migrate_set_speed", "s", do_migrate_set_speed,
       "value", "set maximum speed (in bytes) for migrations" },
+    { "cpu_set", "i", do_cpu_set_nr, "value", "number of cpus in the guest" },
     { NULL, NULL, },
 };
 
diff --git a/qemu/pc-bios/bios.bin b/qemu/pc-bios/bios.bin
index 7462753c0462e6fc863c0669664d363788e08ff3..7599b8d8956141d3355616c12bad85ac3ee112ae 100644
GIT binary patch
delta 1683
zc${riZ%i9y7=PdE6^^4w)eh>Wp>EBB0Z0EFShO>=S4K7lltS57aK-2@(Tm1KFZ&?U
zVuy0+5R!}G(-H_KEShZ7E<;${TAV!$ewgut7{1iS#9Ls>qOz!k^L-1#IeQ<T_j!K5
z=l9%m&vSRtC>4!Tv^{xa{Z$goxcN`%ptrK|o97yn{knK#QcPC~HwV}Ht)*96E{m)2
z;H}Z&xAub}IyMJmO5%O5nV=r$Ng$R~^NA^6l&G|zNY(>[EMAIL PROTECTED]
zhL-gdpJ;2!K(h_Sin5`qVtTm2D&C*Oz=VaDnhsm3O5_jBH55y49==&-LP45k?xoq<
zRq<^rC$a}7T)fnB<gthgQL!W`vJDfiT-I?i&7L6AY&RK8QX+d)T$EXV<`O_u4=J;6
zoI(vLx7JnFo}4ivKl|[EMAIL PROTECTED]>vZlUK`#m7Evurzs&xOMs_}P}
z9EvWn&q~Fs8Z#nkRUXDvFcUAqZOdLO0GSQhTM1EGY_59n>;4*ha#SLl_txQr$l`Ek
zsya=;8Juv<@(^my3k?&SVmv$~rtm$6yhLoyuuMt4&4Gf?vZ~6BCX&tPVFjLX?Dneo
z-TkEtP%sVrjV7$So||ytb&{9*T7DqVgpRdV6J}l-Y<[EMAIL PROTECTED];1+Z(Ci70nff-
zO;u$*!zWI)>[EMAIL PROTECTED])sxOmerwWJBYZe
z?G=QLm%eZB!kIOJT6}PU2tIxeoWw^{NBYs+w&~whb#~-9dS|{w+m<Yy=dko*XZbz`
zmt7KUrA4zR(A_`JHTdp5l#W9&[EMAIL PROTECTED]<8Sq95-9T6=EuVLjF35HFSxXa2*ySh#nV$r0L
[EMAIL PROTECTED]
zf;z<[EMAIL PROTECTED]([EMAIL PROTECTED])24gEnBi3_yX23U_pRz(;TswZk1WvI9Gae92B-K9nKz
zp|[EMAIL PROTECTED]([EMAIL PROTECTED]&HKV^e9k$=`_3qc$5tP4&pJ
zgYoj719<*;%I|HuxdDxvw{f2ar*&IOheqkpC><K5L!*p1wxv#u)Txm=HBzTW>fBZ`
z8YQDqG8!eLQ8HMG#!wr6B;kFf=))`Ur71f0vX#o7UqCPJ*lSa8Pn89IP;NqSrG7MW
z;<ucAiMxS*LS+c$X0wL7_47gr7ux`W{?6K1VhTQK&VVf{rBE97i?Nj{xI1zYu>nr}
zi;LaXaRYN%!%Ao<b>|[EMAIL PROTECTED])
zaA^LQ(DL(c1FGivUp1RJ&;1%&wzx}BxqbhZ6Xy|TxH1qvx%u>[EMAIL PROTECTED]|fL}p9
j{-J^C$j5NuX;?qqya=D#55v>K20RN3>uYQ-kRAUA;utKq

delta 1195
[EMAIL PROTECTED]>kKOGq;!1^9nK1oGFgjx5
z3bP$Zx!G<pnHZjUAUv$;Lt`^26^+hPyGv^yYD`)hUZ`o>v0w{LtFa|[EMAIL PROTECTED]
[EMAIL PROTECTED]|4v6pMN4+}K7-Y<M&4|_|([EMAIL PROTECTED]|vLa
z8^6AoII|TDLOBKHpVjxhg%ooVpG3|xf|{(6sFE&B87pxE8o;XtvI1anzhM|dV}49M
z_KejpsLi!=u<#saU0*Q_lujIA(UUQf80`|2+B%l$#_QPBpiMblcV}%IhBUW(Da}<Z
zqVp_|xSgYtpfuLMR4QRf)@Z~X7?rZSTIn=*luC2QXjx+r*MMd+Tz4m~LZ4Me>Nf`t
z+i+zyEDbtn5N}*W4p!&?FpT&GJ)6ZJin2`n&>W&!eFIU#b8#mrC*x%Sm|MwsOCa7Q
zPn8aQ(Yv!;Q{28S8;RaGlL)0s(-gc;^c$O20g(1W$7r{p_<aRd2Wg(t<qNKwTsDlv
zS&+E7ja;W{z7beNnkGM3ME9S}UWQ_R>@VCh%dKq7a&[EMAIL PROTECTED]<9G<
zsWw4LHMLVALD|w==?sx(7CknMj5R8#oy``Q--%OH#!5;f1&KwZlBoYf3I|7^iNc+3
z3)H([EMAIL PROTECTED];tsfg<XhpnMx>Av<>[EMAIL PROTECTED])[EMAIL PROTECTED]
z{1beJ$ER!xeL#+W94aV|65Cm^%w?NAif{ikTi|<3csoIq!U<Imt%U`|2i33)Y5&3z
z8YJ==wB{W_S<`YVmmC^v71Tsak1dBx4r+?MV|`zpqun2DKPKmK{%{#^UjZQJA1H?=
zc!e^-s}>XNrcF>`H9=*L3952UP|ZAtVt;s#%_JSPo4}iw1-1VTkx`f4a$Qp0Z(oJu
[EMAIL PROTECTED];[EMAIL PROTECTED]<M_DqXTUS0vB
z_2JWDH3>Ht{s{h+QaWQ&wc&*%T-P^_)gX`l<mCqzJ~p-NScnX!9uDEG$0n}RFTIed
ztjs@(@F+EZ%3~MZdQVm*-VvO8-IFI4>L>ndI5_=FWd5MXf!%8V=T?cP`ClXR#U3ZN
z+y2ZBP2-$vJl1~v`RkwFE&JgGPF%eVKZg_2NASy+Vbz3h25#R9J14{y*bj57c9m6w
H<v0HZp>4X&

-- 
1.5.0.6

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel

Reply via email to