diff mbox

kvm tools: Implement keyboard reset method

Message ID 1308316409-9825-1-git-send-email-levinsasha928@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Sasha Levin June 17, 2011, 1:13 p.m. UTC
Implement the keyboard reset method which allows guest kernel
to reboot the guest using the keyboard controller.

This will allow guest kernel to reboot the guest when it needs to,
for example - kernel panic (when passing "panic=1" as kernel parameter).

Based on Pekka Enberg's patch.

Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
---
 tools/kvm/hw/i8042.c        |    8 ++++++--
 tools/kvm/include/kvm/kvm.h |    2 ++
 tools/kvm/kvm-cpu.c         |    2 +-
 tools/kvm/kvm-run.c         |    4 ++--
 4 files changed, 11 insertions(+), 5 deletions(-)

Comments

Pekka Enberg June 17, 2011, 1:50 p.m. UTC | #1
On Fri, 17 Jun 2011, Sasha Levin wrote:
> Implement the keyboard reset method which allows guest kernel
> to reboot the guest using the keyboard controller.
>
> This will allow guest kernel to reboot the guest when it needs to,
> for example - kernel panic (when passing "panic=1" as kernel parameter).
>
> Based on Pekka Enberg's patch.
>
> Signed-off-by: Sasha Levin <levinsasha928@gmail.com>

Does this work for you? For me it get stuck with this:

[    0.833234] Rebooting in 1 seconds..
  #
  # vCPU #0's dump:
  #

  Registers:
  ----------
  rip: ffffffff8106130a   rsp: ffff880013c03f88 flags: 0000000000000046
  rax: ffffffff81c15300   rbx: ffffffff81c00010   rcx: 0000000031798af5
  rdx: 0000000000000000   rsi: 00000000000000ff   rdi: 00000000000000f0
  rbp: ffff880013c03f88    r8: 0000000000000000    r9: 0000000000000000
  r10: 0000000000000000   r11: 0000000000000001   r12: 0000000000000000
  r13: 0000000000000000   r14: ffffffffffffffff   r15: 0000000000013d70
  cr0: 000000008005003b   cr2: 0000000000000000   cr3: 0000000001c03000
  cr4: 00000000000006f0   cr8: 0000000000000000

  Segment registers:
  ------------------
  register  selector  base              limit     type  p dpl db s l g avl
  cs        0010      0000000000000000  ffffffff  0b    1 0   0  1 1 1 0
  ss        0018      0000000000000000  ffffffff  03    1 0   1  1 0 1 0
  ds        0000      0000000000000000  ffffffff  00    0 0   0  0 0 0 0
  es        0000      0000000000000000  ffffffff  00    0 0   0  0 0 0 0
  fs        0000      0000000000000000  ffffffff  00    0 0   0  0 0 0 0
  gs        0000      ffff880013c00000  ffffffff  00    0 0   0  0 0 0 0
  tr        0040      ffff880013c0ec00  00002087  0b    1 0   0  0 0 0 0
  ldt       0000      0000000000000000  ffffffff  00    0 0   0  0 0 0 0
  gdt                 ffff880013c04000  0000007f
  idt                 ffffffff81da7000  00000fff

  APIC:
  -----
  efer: 0000000000000d01  apic base: 00000000fee00900  nmi: enabled

  Interrupt bitmap:
  -----------------
  0000000000000000 0000000000000000 0000000000000000 0000000000000000

  Code:
  -----
  rip: [<ffffffff8106130a>] <unknown>



  Stack:
  ------

which seems to be in native_halt:

ffffffff81061300 t native_halt
ffffffff81061310 t native_clts

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Sasha Levin June 17, 2011, 2:17 p.m. UTC | #2
On Fri, 2011-06-17 at 16:50 +0300, Pekka Enberg wrote:
> On Fri, 17 Jun 2011, Sasha Levin wrote:
> > Implement the keyboard reset method which allows guest kernel
> > to reboot the guest using the keyboard controller.
> >
> > This will allow guest kernel to reboot the guest when it needs to,
> > for example - kernel panic (when passing "panic=1" as kernel parameter).
> >
> > Based on Pekka Enberg's patch.
> >
> > Signed-off-by: Sasha Levin <levinsasha928@gmail.com>
> 
> Does this work for you? For me it get stuck with this:
> 
> [    0.833234] Rebooting in 1 seconds..
>   #
>   # vCPU #0's dump:
>   #
> 
>   Registers:
>   ----------
>   rip: ffffffff8106130a   rsp: ffff880013c03f88 flags: 0000000000000046
>   rax: ffffffff81c15300   rbx: ffffffff81c00010   rcx: 0000000031798af5
>   rdx: 0000000000000000   rsi: 00000000000000ff   rdi: 00000000000000f0
>   rbp: ffff880013c03f88    r8: 0000000000000000    r9: 0000000000000000
>   r10: 0000000000000000   r11: 0000000000000001   r12: 0000000000000000
>   r13: 0000000000000000   r14: ffffffffffffffff   r15: 0000000000013d70
>   cr0: 000000008005003b   cr2: 0000000000000000   cr3: 0000000001c03000
>   cr4: 00000000000006f0   cr8: 0000000000000000
> 
>   Segment registers:
>   ------------------
>   register  selector  base              limit     type  p dpl db s l g avl
>   cs        0010      0000000000000000  ffffffff  0b    1 0   0  1 1 1 0
>   ss        0018      0000000000000000  ffffffff  03    1 0   1  1 0 1 0
>   ds        0000      0000000000000000  ffffffff  00    0 0   0  0 0 0 0
>   es        0000      0000000000000000  ffffffff  00    0 0   0  0 0 0 0
>   fs        0000      0000000000000000  ffffffff  00    0 0   0  0 0 0 0
>   gs        0000      ffff880013c00000  ffffffff  00    0 0   0  0 0 0 0
>   tr        0040      ffff880013c0ec00  00002087  0b    1 0   0  0 0 0 0
>   ldt       0000      0000000000000000  ffffffff  00    0 0   0  0 0 0 0
>   gdt                 ffff880013c04000  0000007f
>   idt                 ffffffff81da7000  00000fff
> 
>   APIC:
>   -----
>   efer: 0000000000000d01  apic base: 00000000fee00900  nmi: enabled
> 
>   Interrupt bitmap:
>   -----------------
>   0000000000000000 0000000000000000 0000000000000000 0000000000000000
> 
>   Code:
>   -----
>   rip: [<ffffffff8106130a>] <unknown>
> 
> 
> 
>   Stack:
>   ------
> 
> which seems to be in native_halt:
> 
> ffffffff81061300 t native_halt
> ffffffff81061310 t native_clts
> 

Yes:
[    1.844359] Rebooting in 1 seconds..
  # KVM session ended normally.

Can you try passing "reboot=k" as an additional kernel parameter and see
if it works then? Maybe keyboard reset isn't set as default.
Pekka Enberg June 17, 2011, 7:16 p.m. UTC | #3
On Fri, 17 Jun 2011, Sasha Levin wrote:
> Yes:
> [    1.844359] Rebooting in 1 seconds..
>  # KVM session ended normally.
>
> Can you try passing "reboot=k" as an additional kernel parameter and see
> if it works then? Maybe keyboard reset isn't set as default.

Yup, that works. I'll add it as default kernel parameter too.
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Pekka Enberg June 17, 2011, 7:26 p.m. UTC | #4
On Fri, 17 Jun 2011, Sasha Levin wrote:
> Yes:
> [    1.844359] Rebooting in 1 seconds..
>  # KVM session ended normally.
>
> Can you try passing "reboot=k" as an additional kernel parameter and see
> if it works then? Maybe keyboard reset isn't set as default.

It still doesn't work reliably. The problem is that if CPU1, for example, 
receives the ioport write, we'll wait for CPU0 forever.

 			Pekka
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/tools/kvm/hw/i8042.c b/tools/kvm/hw/i8042.c
index 21a779e..0bcf7e6 100644
--- a/tools/kvm/hw/i8042.c
+++ b/tools/kvm/hw/i8042.c
@@ -30,6 +30,7 @@ 
 #define I8042_CMD_AUX_TEST	0xA9
 #define I8042_CMD_AUX_DISABLE	0xA7
 #define I8042_CMD_AUX_ENABLE	0xA8
+#define I8042_CMD_SYSTEM_RESET	0xFE
 
 #define RESPONSE_ACK		0xFA
 
@@ -138,7 +139,7 @@  void kbd_queue(u8 c)
 	kbd_update_irq();
 }
 
-static void kbd_write_command(u8 val)
+static void kbd_write_command(struct kvm *kvm, u8 val)
 {
 	switch (val) {
 	case I8042_CMD_CTL_RCTR:
@@ -159,6 +160,9 @@  static void kbd_write_command(u8 val)
 	case I8042_CMD_AUX_ENABLE:
 		state.mode &= ~MODE_DISABLE_AUX;
 		break;
+	case I8042_CMD_SYSTEM_RESET:
+		kvm->stopped = true;
+		break;
 	default:
 		break;
 	}
@@ -314,7 +318,7 @@  static bool kbd_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data
 	switch (port) {
 	case I8042_COMMAND_REG: {
 		u8 value = ioport__read8(data);
-		kbd_write_command(value);
+		kbd_write_command(kvm, value);
 		break;
 	}
 	case I8042_DATA_REG: {
diff --git a/tools/kvm/include/kvm/kvm.h b/tools/kvm/include/kvm/kvm.h
index 7d90d35..d647ecf 100644
--- a/tools/kvm/include/kvm/kvm.h
+++ b/tools/kvm/include/kvm/kvm.h
@@ -41,6 +41,8 @@  struct kvm {
 	const char		*vmlinux;
 	struct disk_image       **disks;
 	int                     nr_disks;
+
+	bool			stopped;
 };
 
 struct kvm *kvm__init(const char *kvm_dev, u64 ram_size);
diff --git a/tools/kvm/kvm-cpu.c b/tools/kvm/kvm-cpu.c
index 1fb1c74..35b3bd7 100644
--- a/tools/kvm/kvm-cpu.c
+++ b/tools/kvm/kvm-cpu.c
@@ -433,7 +433,7 @@  int kvm_cpu__start(struct kvm_cpu *cpu)
 	kvm_cpu__setup_cpuid(cpu);
 	kvm_cpu__reset_vcpu(cpu);
 
-	for (;;) {
+	while (!cpu->kvm->stopped) {
 		if (cpu->paused) {
 			kvm__notify_paused();
 			cpu->paused = 0;
diff --git a/tools/kvm/kvm-run.c b/tools/kvm/kvm-run.c
index 6ad55aa..1310e39 100644
--- a/tools/kvm/kvm-run.c
+++ b/tools/kvm/kvm-run.c
@@ -648,17 +648,17 @@  int kvm_cmd_run(int argc, const char **argv, const char *prefix)
 
 	kvm__init_ram(kvm);
 
+	kbd__init(kvm);
+
 	if (vnc || sdl)
 		fb = vesa__init(kvm);
 
 	if (vnc) {
-		kbd__init(kvm);
 		if (fb)
 			vnc__init(fb);
 	}
 
 	if (sdl) {
-		kbd__init(kvm);
 		if (fb)
 			sdl__init(fb);
 	}