[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 5/5] backdoor: Add guest-side library
From: |
Lluís Vilanova |
Subject: |
[Qemu-devel] [PATCH v2 5/5] backdoor: Add guest-side library |
Date: |
Mon, 05 Dec 2011 23:23:27 +0100 |
User-agent: |
StGit/0.15 |
Guest applications can link against "libqemu-backdoor-guest.a" to use the
backdoor communication channel.
Signed-off-by: Lluís Vilanova <address@hidden>
---
backdoor/guest/Makefile | 18 ++++
backdoor/guest/common.c | 205 ++++++++++++++++++++++++++++++++++++++++
backdoor/guest/qemu-backdoor.h | 59 ++++++++++++
backdoor/qemu/user.c | 2
configure | 2
5 files changed, 285 insertions(+), 1 deletions(-)
create mode 100644 backdoor/guest/Makefile
create mode 100644 backdoor/guest/common.c
create mode 100644 backdoor/guest/qemu-backdoor.h
diff --git a/backdoor/guest/Makefile b/backdoor/guest/Makefile
new file mode 100644
index 0000000..200ee3b
--- /dev/null
+++ b/backdoor/guest/Makefile
@@ -0,0 +1,18 @@
+include ../../../config-host.mak
+include ../../config-target.mak
+include $(SRC_PATH)/rules.mak
+
+vpath % $(SRC_PATH)/backdoor/guest
+
+QEMU_CFLAGS += $(GLIB_CFLAGS)
+QEMU_CFLAGS += -I../../../
+QEMU_CFLAGS += -I../../
+
+obj-y = common.o
+
+libqemu-backdoor-guest.a: $(obj-y)
+
+all: libqemu-backdoor-guest.a
+
+clean:
+ rm -f $(obj-y) libqemu-backdoor-guest.a
diff --git a/backdoor/guest/common.c b/backdoor/guest/common.c
new file mode 100644
index 0000000..2238dfa
--- /dev/null
+++ b/backdoor/guest/common.c
@@ -0,0 +1,205 @@
+/*
+ * Guest-side management of backdoor channels.
+ *
+ * Copyright (C) 2011 Lluís Vilanova <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu-backdoor.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <glob.h>
+
+#include "config-target.h"
+#include "hw/pci_ids.h"
+#include "hw/pci.h"
+
+
+static char *data_path = NULL;
+static char *control_path = NULL;
+static int data_fd = -1;
+static int control_fd = -1;
+
+static void *data_addr = NULL;
+static void *control_addr = NULL;
+
+
+static int init_channel_file(const char *base, const char *suffix, size_t size,
+ char ** path, int *fd, void **addr)
+{
+ *path = malloc(strlen(base) + strlen(suffix) + 1);
+ sprintf(*path, "%s%s", base, suffix);
+
+ *fd = open(*path, O_RDWR);
+ if (*fd == -1) {
+ return -1;
+ }
+
+ *addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, *fd, 0);
+ if (*addr == MAP_FAILED) {
+ return -1;
+ }
+ return 0;
+}
+
+#if !defined(CONFIG_USER_ONLY) && defined(__linux__)
+static int check_device_id (const char *base, const char *name, uint64_t value)
+{
+ char tmp[1024];
+ sprintf(tmp, "%s/%s", base, name);
+
+ int fd = open(tmp, O_RDONLY);
+ if (fd < 0) {
+ return -1;
+ }
+
+ char v[1024];
+ ssize_t s = read(fd, v, sizeof(v));
+ if (s < 0) {
+ close(fd);
+ return -1;
+ }
+ v[s] = '\0';
+
+ char *end;
+ uint64_t vv = strtoull(v, &end, 16);
+ if (*end == '\n' && vv == value) {
+ return 0;
+ }
+ else {
+ return -1;
+ }
+}
+
+static char* find_device(void)
+{
+ static char tmp[1024];
+ char *res = NULL;
+
+ glob_t g;
+ if (glob("/sys/devices/pci*/*", GLOB_NOSORT, NULL, &g) != 0) {
+ return NULL;
+ }
+
+
+ int i;
+ for (i = 0; i < g.gl_pathc; i++) {
+ char *path = g.gl_pathv[i];
+
+ if (check_device_id(path, "vendor", PCI_VENDOR_ID_REDHAT_QUMRANET) <
0) {
+ continue;
+ }
+ if (check_device_id(path, "device", PCI_DEVICE_ID_BACKDOOR) < 0) {
+ continue;
+ }
+
+ sprintf(tmp, "%s", path);
+ res = tmp;
+ break;
+ }
+
+ globfree(&g);
+
+ return res;
+}
+#endif
+
+int qemu_backdoor_init(const char *base)
+{
+#if defined(CONFIG_USER_ONLY)
+ const char *control_suff = "-control";
+ const size_t control_size = getpagesize() * 2;
+ const char *data_suff = "-data";
+#elif defined(__linux__)
+ const char *control_suff = "/resource0";
+ const size_t control_size = getpagesize();
+ const char *data_suff = "/resource1";
+#else
+#error Unsupported OS
+#endif
+
+#if !defined(CONFIG_USER_ONLY)
+ if (base == NULL) {
+ /* try to guess the base path */
+ base = find_device();
+ if (base == NULL) {
+ return -1;
+ }
+ }
+#endif
+
+ int res;
+ res = init_channel_file(base, control_suff, control_size,
+ &control_path, &control_fd, &control_addr);
+ if (res != 0) {
+ return res;
+ }
+
+ res = init_channel_file(base, data_suff, qemu_backdoor_data_size(),
+ &data_path, &data_fd, &data_addr);
+ if (res != 0) {
+ return res;
+ }
+ return 0;
+}
+
+
+static int fini_channel(int *fd, char **path)
+{
+ if (*fd != -1) {
+ if (close(*fd) == -1) {
+ return -1;
+ }
+ *fd = -1;
+ }
+ if (*path != NULL) {
+ free(*path);
+ *path = NULL;
+ }
+ return 0;
+}
+
+int qemu_backdoor_fini(void)
+{
+ if (fini_channel(&data_fd, &data_path) != 0) {
+ return -1;
+ }
+ if (fini_channel(&control_fd, &control_path) != 0) {
+ return -1;
+ }
+ return 0;
+}
+
+
+uint64_t qemu_backdoor_data_size(void)
+{
+ return *(uint64_t*)control_addr;
+}
+
+void *qemu_backdoor_data(void)
+{
+ return data_addr;
+}
+
+void qemu_backdoor (uint64_t cmd)
+{
+ uint64_t *ctrl;
+ ctrl = control_addr;
+ ctrl[1] = cmd;
+#if defined(CONFIG_USER_ONLY)
+ /* QEMU in 'user' mode uses two faulting pages to detect invocations */
+ ctrl = control_addr + getpagesize();
+ ctrl[1] = cmd;
+#endif
+}
diff --git a/backdoor/guest/qemu-backdoor.h b/backdoor/guest/qemu-backdoor.h
new file mode 100644
index 0000000..0e34dc9
--- /dev/null
+++ b/backdoor/guest/qemu-backdoor.h
@@ -0,0 +1,59 @@
+/*
+ * Guest-side management of backdoor channels.
+ *
+ * Copyright (C) 2011 Lluís Vilanova <address@hidden>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+
+/**
+ * Initialize the backdoor channel.
+ *
+ * The base path to the backdoor channel is dependant on the type of QEMU
+ * target:
+ *
+ * - User (single-application)
+ * The base path provided when starting QEMU ("-backdoor" commandline
option).
+ *
+ * - Softmmu (full-system); OS-dependant
+ * - Linux: The base path to the backdoor channel virtual device (on a
default
+ * device setup for x86 this is "/sys/devices/pci0000:00/0000:00:04.0"). If
+ * NULL is provided, the first backdoor device to be found will be used.
+ *
+ * @param base Base path to the backdoor channel.
+ * @return Zero on success.
+ */
+int qemu_backdoor_init(const char *base);
+
+/**
+ * Deinitialize the backdoor channel.
+ *
+ * @return Zero on success.
+ */
+int qemu_backdoor_fini(void);
+
+/**
+ * The amount of data that can be passed through the data channel.
+ */
+uint64_t qemu_backdoor_data_size(void);
+
+/**
+ * Pointer to the start of the data channel.
+ */
+void *qemu_backdoor_data(void);
+
+/**
+ * Invoke the control channel.
+ *
+ * The command in the control channel can be used to, e.g., differentiate
+ * between multiple users of the backdoor channel without resorting to the data
+ * channel for deambiguation.
+ *
+ * @param cmd Integral number passed out-of-band w.r.t the data channel.
+ */
+void qemu_backdoor(uint64_t cmd);
diff --git a/backdoor/qemu/user.c b/backdoor/qemu/user.c
index 6e178cc..54d797f 100644
--- a/backdoor/qemu/user.c
+++ b/backdoor/qemu/user.c
@@ -114,7 +114,7 @@ static void fini_channel(int *fd, char **path)
*fd = -1;
}
if (*path != NULL) {
- g_free(path);
+ g_free(*path);
*path = NULL;
}
}
diff --git a/configure b/configure
index 8af8313..67d4c9a 100755
--- a/configure
+++ b/configure
@@ -3374,6 +3374,8 @@ if test -n "$backdoor"; then
mkdir -p $target_dir/libbackdoor
symlink $backdoor/Makefile $target_dir/libbackdoor/Makefile
mkdir -p $target_dir/backdoor/qemu
+ mkdir -p $target_dir/backdoor/guest
+ symlink $source_path/backdoor/guest/Makefile
$target_dir/backdoor/guest/Makefile
fi
- Re: [Qemu-devel] [PATCH v2 4/5] backdoor: [softmmu] Add QEMU-side proxy to "libbackdoor.a", (continued)
- Re: [Qemu-devel] [PATCH v2 4/5] backdoor: [softmmu] Add QEMU-side proxy to "libbackdoor.a", Lluís Vilanova, 2011/12/06
- Re: [Qemu-devel] [PATCH v2 4/5] backdoor: [softmmu] Add QEMU-side proxy to "libbackdoor.a", Anthony Liguori, 2011/12/06
- Re: [Qemu-devel] [PATCH v2 4/5] backdoor: [softmmu] Add QEMU-side proxy to "libbackdoor.a", Peter Maydell, 2011/12/06
- [Qemu-devel] Insane virtio-serial semantics (was: [PATCH v2 4/5] backdoor: [softmmu] Add QEMU-side proxy to "libbackdoor.a"), Markus Armbruster, 2011/12/07
- Re: [Qemu-devel] Insane virtio-serial semantics, Anthony Liguori, 2011/12/07
- Re: [Qemu-devel] Insane virtio-serial semantics, Michael Roth, 2011/12/07
- Re: [Qemu-devel] Insane virtio-serial semantics, Anthony Liguori, 2011/12/07
- Re: [Qemu-devel] Insane virtio-serial semantics, Markus Armbruster, 2011/12/08
- Re: [Qemu-devel] Insane virtio-serial semantics, Anthony Liguori, 2011/12/08
- Re: [Qemu-devel] [PATCH v2 4/5] backdoor: [softmmu] Add QEMU-side proxy to "libbackdoor.a", Lluís Vilanova, 2011/12/06
[Qemu-devel] [PATCH v2 5/5] backdoor: Add guest-side library,
Lluís Vilanova <=
Re: [Qemu-devel] [PATCH v2 0/5] backdoor: lightweight guest-to-QEMU backdoor channel, Anthony Liguori, 2011/12/06
- Re: [Qemu-devel] [PATCH v2 0/5] backdoor: lightweight guest-to-QEMU backdoor channel, Lluís Vilanova, 2011/12/07
- Re: [Qemu-devel] [PATCH v2 0/5] backdoor: lightweight guest-to-QEMU backdoor channel, Anthony Liguori, 2011/12/07
- Re: [Qemu-devel] [PATCH v2 0/5] backdoor: lightweight guest-to-QEMU backdoor channel, Lluís Vilanova, 2011/12/07
- Re: [Qemu-devel] [PATCH v2 0/5] backdoor: lightweight guest-to-QEMU backdoor channel, Anthony Liguori, 2011/12/07
- Re: [Qemu-devel] [PATCH v2 0/5] backdoor: lightweight guest-to-QEMU backdoor channel, Lluís Vilanova, 2011/12/07
- Re: [Qemu-devel] [PATCH v2 0/5] backdoor: lightweight guest-to-QEMU backdoor channel, Anthony Liguori, 2011/12/07
- Re: [Qemu-devel] [PATCH v2 0/5] backdoor: lightweight guest-to-QEMU backdoor channel, Lluís Vilanova, 2011/12/07
- Re: [Qemu-devel] [PATCH v2 0/5] backdoor: lightweight guest-to-QEMU backdoor channel, Peter Maydell, 2011/12/07
- Re: [Qemu-devel] [PATCH v2 0/5] backdoor: lightweight guest-to-QEMU backdoor channel, Anthony Liguori, 2011/12/07