@@ -5,6 +5,7 @@
#include <kvm/parse-options.h>
#include <kvm/kvm-ipc.h>
#include <kvm/read-write.h>
+#include <kvm/virtio-iommu.h>
#include <stdio.h>
#include <string.h>
@@ -17,6 +18,7 @@ static int nmi = -1;
static bool dump;
static const char *instance_name;
static const char *sysrq;
+static const char *iommu;
static const char * const debug_usage[] = {
"lkvm debug [--all] [-n name] [-d] [-m vcpu]",
@@ -28,6 +30,7 @@ static const struct option debug_options[] = {
OPT_BOOLEAN('d', "dump", &dump, "Generate a debug dump from guest"),
OPT_INTEGER('m', "nmi", &nmi, "Generate NMI on VCPU"),
OPT_STRING('s', "sysrq", &sysrq, "sysrq", "Inject a sysrq"),
+ OPT_STRING('i', "iommu", &iommu, "params", "Debug virtual IOMMU"),
OPT_GROUP("Instance options:"),
OPT_BOOLEAN('a', "all", &all, "Debug all instances"),
OPT_STRING('n', "name", &instance_name, "name", "Instance name"),
@@ -68,11 +71,14 @@ static int do_debug(const char *name, int sock)
cmd.sysrq = sysrq[0];
}
+ if (iommu && !viommu_parse_debug_string(iommu, &cmd.iommu))
+ cmd.dbg_type |= KVM_DEBUG_CMD_TYPE_IOMMU;
+
r = kvm_ipc__send_msg(sock, KVM_IPC_DEBUG, sizeof(cmd), (u8 *)&cmd);
if (r < 0)
return r;
- if (!dump)
+ if (!(cmd.dbg_type & KVM_DEBUG_CMD_DUMP_MASK))
return 0;
do {
@@ -2,16 +2,22 @@
#define KVM__DEBUG_H
#include <kvm/util.h>
+#include <kvm/iommu.h>
#include <linux/types.h>
#define KVM_DEBUG_CMD_TYPE_DUMP (1 << 0)
#define KVM_DEBUG_CMD_TYPE_NMI (1 << 1)
#define KVM_DEBUG_CMD_TYPE_SYSRQ (1 << 2)
+#define KVM_DEBUG_CMD_TYPE_IOMMU (1 << 3)
+
+#define KVM_DEBUG_CMD_DUMP_MASK \
+ (KVM_DEBUG_CMD_TYPE_IOMMU | KVM_DEBUG_CMD_TYPE_DUMP)
struct debug_cmd_params {
u32 dbg_type;
u32 cpu;
char sysrq;
+ struct iommu_debug_params iommu;
};
int kvm_cmd_debug(int argc, const char **argv, const char *prefix);
@@ -1,6 +1,7 @@
#ifndef KVM_IOMMU_H
#define KVM_IOMMU_H
+#include <stdbool.h>
#include <stdlib.h>
#include "devices.h"
@@ -10,6 +11,10 @@
#define IOMMU_PROT_WRITE 0x2
#define IOMMU_PROT_EXEC 0x4
+struct iommu_debug_params {
+ bool print_enabled;
+};
+
/*
* Test if mapping is present. If not, return an error but do not report it to
* stderr
@@ -7,4 +7,9 @@ const struct iommu_properties *viommu_get_properties(void *dev);
void *viommu_register(struct kvm *kvm, struct iommu_properties *props);
void viommu_unregister(struct kvm *kvm, void *cookie);
+struct iommu_debug_params;
+
+int viommu_parse_debug_string(const char *options, struct iommu_debug_params *);
+int viommu_debug(int fd, struct iommu_debug_params *);
+
#endif
@@ -14,6 +14,7 @@
#include "kvm/strbuf.h"
#include "kvm/kvm-cpu.h"
#include "kvm/8250-serial.h"
+#include "kvm/virtio-iommu.h"
struct kvm_ipc_head {
u32 type;
@@ -424,31 +425,35 @@ static void handle_debug(struct kvm *kvm, int fd, u32 type, u32 len, u8 *msg)
pthread_kill(kvm->cpus[vcpu]->thread, SIGUSR1);
}
- if (!(dbg_type & KVM_DEBUG_CMD_TYPE_DUMP))
- return;
+ if (dbg_type & KVM_DEBUG_CMD_TYPE_IOMMU)
+ viommu_debug(fd, ¶ms->iommu);
- for (i = 0; i < kvm->nrcpus; i++) {
- struct kvm_cpu *cpu = kvm->cpus[i];
+ if (dbg_type & KVM_DEBUG_CMD_TYPE_DUMP) {
+ for (i = 0; i < kvm->nrcpus; i++) {
+ struct kvm_cpu *cpu = kvm->cpus[i];
- if (!cpu)
- continue;
+ if (!cpu)
+ continue;
- printout_done = 0;
+ printout_done = 0;
+
+ kvm_cpu__set_debug_fd(fd);
+ pthread_kill(cpu->thread, SIGUSR1);
+ /*
+ * Wait for the vCPU to dump state before signalling
+ * the next thread. Since this is debug code it does
+ * not matter that we are burning CPU time a bit:
+ */
+ while (!printout_done)
+ sleep(0);
+ }
- kvm_cpu__set_debug_fd(fd);
- pthread_kill(cpu->thread, SIGUSR1);
- /*
- * Wait for the vCPU to dump state before signalling
- * the next thread. Since this is debug code it does
- * not matter that we are burning CPU time a bit:
- */
- while (!printout_done)
- sleep(0);
+ serial8250__inject_sysrq(kvm, 'p');
}
- close(fd);
-
- serial8250__inject_sysrq(kvm, 'p');
+ if (dbg_type & KVM_DEBUG_CMD_DUMP_MASK)
+ /* builtin-debug is reading, signal EOT */
+ close(fd);
}
int kvm_ipc__init(struct kvm *kvm)
@@ -620,3 +620,17 @@ void viommu_unregister(struct kvm *kvm, void *viommu)
{
free(viommu);
}
+
+int viommu_parse_debug_string(const char *cmdline, struct iommu_debug_params *params)
+{
+ /* show instances numbers */
+ /* send command to instance */
+ /* - dump mappings */
+ /* - statistics */
+ return -ENOSYS;
+}
+
+int viommu_debug(int sock, struct iommu_debug_params *params)
+{
+ return -ENOSYS;
+}
Add a new parameter to lkvm debug, '-i' or '--iommu'. Commands will be added later. For the moment, rework the debug builtin to share dump facilities with the '-d'/'--dump' parameter. Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com> --- builtin-debug.c | 8 +++++++- include/kvm/builtin-debug.h | 6 ++++++ include/kvm/iommu.h | 5 +++++ include/kvm/virtio-iommu.h | 5 +++++ kvm-ipc.c | 43 ++++++++++++++++++++++++------------------- virtio/iommu.c | 14 ++++++++++++++ 6 files changed, 61 insertions(+), 20 deletions(-)