@@ -53,6 +53,29 @@ static struct serial8250_device devices[] = {
},
};
+#define SYSRQ_PENDING_NONE 0
+#define SYSRQ_PENDING_BREAK 1
+#define SYSRQ_PENDING_CMD 2
+
+static int sysrq_pending;
+
+static void serial8250__sysrq(struct kvm *self, struct serial8250_device *dev)
+{
+ switch (sysrq_pending) {
+ case SYSRQ_PENDING_BREAK:
+ dev->lsr |= UART_LSR_DR | UART_LSR_BI;
+
+ sysrq_pending = SYSRQ_PENDING_CMD;
+ break;
+ case SYSRQ_PENDING_CMD:
+ dev->rbr = 'p';
+ dev->lsr |= UART_LSR_DR;
+
+ sysrq_pending = SYSRQ_PENDING_NONE;
+ break;
+ }
+}
+
static void serial8250__receive(struct kvm *self, struct serial8250_device *dev)
{
int c;
@@ -60,6 +83,11 @@ static void serial8250__receive(struct kvm *self, struct serial8250_device *dev)
if (dev->lsr & UART_LSR_DR)
return;
+ if (sysrq_pending) {
+ serial8250__sysrq(self, dev);
+ return;
+ }
+
if (!term_readable(CONSOLE_8250))
return;
@@ -94,6 +122,11 @@ void serial8250__inject_interrupt(struct kvm *self)
}
}
+void serial8250__inject_sysrq(struct kvm *self)
+{
+ sysrq_pending = SYSRQ_PENDING_BREAK;
+}
+
static struct serial8250_device *find_device(uint16_t port)
{
unsigned int i;
@@ -5,5 +5,6 @@ struct kvm;
void serial8250__init(struct kvm *kvm);
void serial8250__inject_interrupt(struct kvm *kvm);
+void serial8250__inject_sysrq(struct kvm *kvm);
#endif /* KVM__8250_SERIAL_H */
@@ -38,6 +38,7 @@ static void handle_sigint(int sig)
static void handle_sigquit(int sig)
{
+ serial8250__inject_sysrq(kvm);
kvm__show_registers(kvm);
kvm__show_code(kvm);
kvm__show_page_tables(kvm);
This patch makes SIGQUIT to the host hypervisor send 'SysRq-P' to the guest kernel via 8250 serial console to make debugging stuck guests easier. Cc: Asias He <asias.hejun@gmail.com> Cc: Cyrill Gorcunov <gorcunov@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Pekka Enberg <penberg@kernel.org> --- tools/kvm/8250-serial.c | 33 +++++++++++++++++++++++++++++++++ tools/kvm/include/kvm/8250-serial.h | 1 + tools/kvm/main.c | 1 + 3 files changed, 35 insertions(+), 0 deletions(-)