aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/xen.h1
-rw-r--r--hw/xen_common.h12
-rw-r--r--hw/xen_console.c16
-rw-r--r--xen-all.c60
-rw-r--r--xen-stub.c4
5 files changed, 87 insertions, 6 deletions
diff --git a/hw/xen.h b/hw/xen.h
index 95029bb..e432705 100644
--- a/hw/xen.h
+++ b/hw/xen.h
@@ -41,6 +41,7 @@ qemu_irq *xen_interrupt_controller_init(void);
int xen_init(void);
int xen_hvm_init(void);
void xen_vcpu_init(void);
+void xenstore_store_pv_console_info(int i, struct CharDriverState *chr);
#if defined(NEED_CPU_H) && !defined(CONFIG_USER_ONLY)
void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size);
diff --git a/hw/xen_common.h b/hw/xen_common.h
index 2c79af6..0409ac7 100644
--- a/hw/xen_common.h
+++ b/hw/xen_common.h
@@ -85,6 +85,18 @@ static inline int xc_domain_add_to_physmap(int xc_handle, uint32_t domid,
return xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
}
+static inline struct xs_handle *xs_open(unsigned long flags)
+{
+ return xs_daemon_open();
+}
+
+static inline void xs_close(struct xs_handle *xsh)
+{
+ if (xsh != NULL) {
+ xs_daemon_close(xsh);
+ }
+}
+
/* Xen 4.1 */
#else
diff --git a/hw/xen_console.c b/hw/xen_console.c
index 2d613ee..bdb8540 100644
--- a/hw/xen_console.c
+++ b/hw/xen_console.c
@@ -179,8 +179,9 @@ static void xencons_send(struct XenConsole *con)
static int con_init(struct XenDevice *xendev)
{
struct XenConsole *con = container_of(xendev, struct XenConsole, xendev);
- char *type, *dom;
+ char *type, *dom, label[32];
int ret = 0;
+ const char *output;
/* setup */
dom = xs_get_domain_path(xenstore, con->xendev.dom);
@@ -194,11 +195,14 @@ static int con_init(struct XenDevice *xendev)
goto out;
}
- if (!serial_hds[con->xendev.dev])
- xen_be_printf(xendev, 1, "WARNING: serial line %d not configured\n",
- con->xendev.dev);
- else
- con->chr = serial_hds[con->xendev.dev];
+ output = xenstore_read_str(con->console, "output");
+ /* output is a pty by default */
+ if (output == NULL) {
+ output = "pty";
+ }
+ snprintf(label, sizeof(label), "xencons%d", con->xendev.dev);
+ con->chr = qemu_chr_open(label, output, NULL);
+ xenstore_store_pv_console_info(con->xendev.dev, con->chr);
out:
qemu_free(type);
diff --git a/xen-all.c b/xen-all.c
index fb9bcc8..8105c83 100644
--- a/xen-all.c
+++ b/xen-all.c
@@ -737,6 +737,66 @@ static void cpu_handle_ioreq(void *opaque)
}
}
+static int store_dev_info(int domid, CharDriverState *cs, const char *string)
+{
+ struct xs_handle *xs = NULL;
+ char *path = NULL;
+ char *newpath = NULL;
+ char *pts = NULL;
+ int ret = -1;
+
+ /* Only continue if we're talking to a pty. */
+ if (strncmp(cs->filename, "pty:", 4)) {
+ return 0;
+ }
+ pts = cs->filename + 4;
+
+ /* We now have everything we need to set the xenstore entry. */
+ xs = xs_open(0);
+ if (xs == NULL) {
+ fprintf(stderr, "Could not contact XenStore\n");
+ goto out;
+ }
+
+ path = xs_get_domain_path(xs, domid);
+ if (path == NULL) {
+ fprintf(stderr, "xs_get_domain_path() error\n");
+ goto out;
+ }
+ newpath = realloc(path, (strlen(path) + strlen(string) +
+ strlen("/tty") + 1));
+ if (newpath == NULL) {
+ fprintf(stderr, "realloc error\n");
+ goto out;
+ }
+ path = newpath;
+
+ strcat(path, string);
+ strcat(path, "/tty");
+ if (!xs_write(xs, XBT_NULL, path, pts, strlen(pts))) {
+ fprintf(stderr, "xs_write for '%s' fail", string);
+ goto out;
+ }
+ ret = 0;
+
+out:
+ free(path);
+ xs_close(xs);
+
+ return ret;
+}
+
+void xenstore_store_pv_console_info(int i, CharDriverState *chr)
+{
+ if (i == 0) {
+ store_dev_info(xen_domid, chr, "/console");
+ } else {
+ char buf[32];
+ snprintf(buf, sizeof(buf), "/device/console/%d", i);
+ store_dev_info(xen_domid, chr, buf);
+ }
+}
+
static void xenstore_record_dm_state(XenIOState *s, const char *state)
{
char path[50];
diff --git a/xen-stub.c b/xen-stub.c
index a4f35a1..efe2ab5 100644
--- a/xen-stub.c
+++ b/xen-stub.c
@@ -9,6 +9,10 @@
#include "qemu-common.h"
#include "hw/xen.h"
+void xenstore_store_pv_console_info(int i, CharDriverState *chr)
+{
+}
+
int xen_pci_slot_get_pirq(PCIDevice *pci_dev, int irq_num)
{
return -1;