From: Joao Martins Date: Tue, 21 Aug 2018 16:16:19 +0000 (-0400) Subject: i386/xen: add monitor commands to test event injection X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=a731cf463f1e18f2f9f18c033e0a2f4cf9ce93f4;p=users%2Fdwmw2%2Fqemu.git i386/xen: add monitor commands to test event injection Specifically add listing, injection of event channels. Signed-off-by: Joao Martins --- diff --git a/hmp-commands.hx b/hmp-commands.hx index 3cf1bb7f9a..1dc2a9da2b 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1912,6 +1912,32 @@ ETEXI .cmd = hmp_xen_inject_callback, }, +STEXI +@item xen-event-inject @var{port} +Notify guest via event channel on port @var{port} +ETEXI + + { + .name = "xen-event-inject", + .args_type = "port:i", + .params = "port", + .help = "inject event channel", + .cmd = hmp_xen_event_inject, + }, + +STEXI +@item xen-event-list @var{port} +List event channels in the guest +ETEXI + + { + .name = "xen-event-list", + .args_type = "", + .params = "", + .help = "list event channel state", + .cmd = hmp_xen_event_list, + }, + STEXI @end table ETEXI diff --git a/target/i386/xen.h b/target/i386/xen.h index e1872c8518..6cc7a71898 100644 --- a/target/i386/xen.h +++ b/target/i386/xen.h @@ -29,4 +29,6 @@ void kvm_xen_init(XenState *xen); void kvm_xen_run_on_cpu(CPUState *cpu, run_on_cpu_func func, void *data); void hmp_xen_inject_callback(Monitor *mon, const QDict *qdict); +void hmp_xen_event_list(Monitor *mon, const QDict *qdict); +void hmp_xen_event_inject(Monitor *mon, const QDict *qdict); #endif diff --git a/target/i386/xen_evtchn.c b/target/i386/xen_evtchn.c index 5f62b7f77e..12c6bd8650 100644 --- a/target/i386/xen_evtchn.c +++ b/target/i386/xen_evtchn.c @@ -158,8 +158,7 @@ static void evtchn_2l_vcpu_set_pending(X86CPU *cpu) kvm_xen_vcpu_inject_upcall(cpu); } -static void __attribute__((unused)) evtchn_2l_set_pending(X86CPU *cpu, - XenEvtChn *evtchn) +static void evtchn_2l_set_pending(X86CPU *cpu, XenEvtChn *evtchn) { struct shared_info *shared_info = CPU(cpu)->xen_state->shared_info; struct vcpu_info *vcpu_info = cpu->env.xen_vcpu.info; @@ -185,8 +184,7 @@ static void evtchn_2l_clear_pending(X86CPU *cpu, XenEvtChn *evtchn) clear_bit_atomic(port, (unsigned long *) shared_info->evtchn_pending); } -static bool __attribute__((unused)) evtchn_2l_is_pending(X86CPU *cpu, - XenEvtChn *evtchn) +static bool evtchn_2l_is_pending(X86CPU *cpu, XenEvtChn *evtchn) { struct shared_info *shared_info = CPU(cpu)->xen_state->shared_info; int port = evtchn->port; @@ -194,8 +192,7 @@ static bool __attribute__((unused)) evtchn_2l_is_pending(X86CPU *cpu, return !!test_bit(port, (unsigned long *) shared_info->evtchn_pending); } -static bool __attribute__((unused)) evtchn_2l_is_masked(X86CPU *cpu, - XenEvtChn *evtchn) +static bool evtchn_2l_is_masked(X86CPU *cpu, XenEvtChn *evtchn) { struct shared_info *shared_info = CPU(cpu)->xen_state->shared_info; int port = evtchn->port; @@ -203,8 +200,7 @@ static bool __attribute__((unused)) evtchn_2l_is_masked(X86CPU *cpu, return !!test_bit(port, (unsigned long *) shared_info->evtchn_mask); } -static int __attribute__((unused)) evtchn_2l_state(X86CPU *cpu, - XenEvtChn *evtchn) +static int evtchn_2l_state(X86CPU *cpu, XenEvtChn *evtchn) { struct vcpu_info *vcpu_info = cpu->env.xen_vcpu.info; int port = evtchn->port; @@ -355,3 +351,54 @@ int kvm_xen_evtchn_vcpu_init(X86CPU *cpu, struct vcpu_info *vcpu) return 0; } +void hmp_xen_event_list(Monitor *mon, const QDict *qdict) +{ + struct XenEvtChn *evtchn; + X86CPU *x86_cpu; + CPUState *cpu; + int i, j; + + for (i = 0; i < EVTCHN_MAX_GROUPS; i++) { + for (j = 0; j < EVTCHN_PER_GROUP; j++) { + if (!evtchns[i]) { + continue; + } + + evtchn = &evtchns[i][j]; + cpu = qemu_get_cpu(evtchn->notify_vcpu_id); + x86_cpu = X86_CPU(cpu); + + if (!evtchn) { + continue; + } + if (!evtchn->state) { + continue; + } + + monitor_printf(mon, "port %4u [%c/%c/%d] vcpu %d\n", + evtchn->port, + evtchn_2l_is_pending(x86_cpu, evtchn) ? 'p' : ' ', + evtchn_2l_is_masked(x86_cpu, evtchn) ? 'm' : ' ', + evtchn_2l_state(x86_cpu, evtchn), + evtchn->notify_vcpu_id); + } + } +} + +void hmp_xen_event_inject(Monitor *mon, const QDict *qdict) +{ + int port = qdict_get_int(qdict, "port"); + struct XenEvtChn *evtchn; + CPUState *cpu; + + evtchn = evtchn_from_port(port); + if (!evtchn) { + return; + } + + cpu = qemu_get_cpu(evtchn->notify_vcpu_id); + evtchn_2l_set_pending(X86_CPU(cpu), evtchn); + monitor_printf(mon, "evtchn_set_pending(port:%d,qcpu:%d,vcpu:%d)\n", + port, cpu->cpu_index, evtchn->notify_vcpu_id); +} +