]> www.infradead.org Git - users/dwmw2/qemu.git/commitdiff
i386/xen: add monitor commands to test event injection
authorJoao Martins <joao.m.martins@oracle.com>
Tue, 21 Aug 2018 16:16:19 +0000 (12:16 -0400)
committerJoao Martins <joao.m.martins@oracle.com>
Tue, 19 Feb 2019 14:00:57 +0000 (09:00 -0500)
Specifically add listing, injection of event channels.

Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
hmp-commands.hx
target/i386/xen.h
target/i386/xen_evtchn.c

index 3cf1bb7f9a7623f52bbea72ddebeda3ac7e35831..1dc2a9da2b0420ee483a1877cd7ee55cce9fbea6 100644 (file)
@@ -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
index e1872c85182ea78e559694bc7f00661d6c7c699c..6cc7a718980a0e6617ba6b5291891f507fcf3700 100644 (file)
@@ -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
index 5f62b7f77e40a23d23039e9ab1950a91260ae299..12c6bd865004895fe0adbe3e1e85d8aaf220262f 100644 (file)
@@ -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);
+}
+