Thanks for the feedbacks.
Here a new version of this patch with more error handling.
--
Jean Guyader
diff -r 810d8c3ac992 tools/firmware/hvmloader/config.h
--- a/tools/firmware/hvmloader/config.h Thu May 08 16:58:33 2008 +0100
+++ b/tools/firmware/hvmloader/config.h Fri May 09 16:47:04 2008 +0100
@@ -23,7 +23,7 @@
/* Memory map. */
#define HYPERCALL_PHYSICAL_ADDRESS 0x00080000
#define VGABIOS_PHYSICAL_ADDRESS 0x000C0000
-#define ETHERBOOT_PHYSICAL_ADDRESS 0x000C8000
+#define ETHERBOOT_PHYSICAL_ADDRESS 0x000D0000
#define EXTBOOT_PHYSICAL_ADDRESS 0x000DF800
#define SMBIOS_PHYSICAL_ADDRESS 0x000E9000
#define SMBIOS_MAXIMUM_SIZE 0x00001000
diff -r 810d8c3ac992 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c Thu May 08 16:58:33 2008 +0100
+++ b/tools/firmware/hvmloader/hvmloader.c Fri May 09 16:47:04 2008 +0100
@@ -464,7 +464,16 @@ int main(void)
if ( (get_vcpu_nr() > 1) || get_apic_mode() )
create_mp_tables();
- if ( cirrus_check() )
+ if ( get_vga_pt_enabled() )
+ {
+ printf("Loading dom0 VGABIOS ...\n");
+ printf(" - 0x%x (0x%x)\n", get_vga_pt_bios_paddr(),
get_vga_pt_bios_size());
+ memcpy((void*)VGABIOS_PHYSICAL_ADDRESS,
+ (void*)get_vga_pt_bios_paddr(),
+ get_vga_pt_bios_size());
+ vgabios_sz = get_vga_pt_bios_size();
+ }
+ else if ( cirrus_check() )
{
printf("Loading Cirrus VGABIOS ...\n");
memcpy((void *)VGABIOS_PHYSICAL_ADDRESS,
diff -r 810d8c3ac992 tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c Thu May 08 16:58:33 2008 +0100
+++ b/tools/firmware/hvmloader/util.c Fri May 09 16:47:04 2008 +0100
@@ -594,6 +594,24 @@ int get_vcpu_nr(void)
return (t ? t->nr_vcpus : 1);
}
+int get_vga_pt_enabled(void)
+{
+ struct hvm_info_table *t = get_hvm_info_table();
+ return (t && t->vga_bios_paddr > 0);
+}
+
+int get_vga_pt_bios_paddr(void)
+{
+ struct hvm_info_table *t = get_hvm_info_table();
+ return (t ? t->vga_bios_paddr : 0);
+}
+
+int get_vga_pt_bios_size(void)
+{
+ struct hvm_info_table *t = get_hvm_info_table();
+ return (t ? t->vga_bios_size : -1);
+}
+
int get_acpi_enabled(void)
{
struct hvm_info_table *t = get_hvm_info_table();
diff -r 810d8c3ac992 tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h Thu May 08 16:58:33 2008 +0100
+++ b/tools/firmware/hvmloader/util.h Fri May 09 16:47:04 2008 +0100
@@ -106,6 +106,9 @@ int get_vcpu_nr(void);
int get_vcpu_nr(void);
int get_acpi_enabled(void);
int get_apic_mode(void);
+int get_vga_pt_enabled(void);
+int get_vga_pt_bios_paddr(void);
+int get_vga_pt_bios_size(void);
/* String and memory functions */
int strcmp(const char *cs, const char *ct);
diff -r 810d8c3ac992 tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target Thu May 08 16:58:33 2008 +0100
+++ b/tools/ioemu/Makefile.target Fri May 09 16:47:04 2008 +0100
@@ -499,6 +499,9 @@ COCOA_LIBS+=-framework CoreAudio
COCOA_LIBS+=-framework CoreAudio
endif
endif
+
+VL_OBJS+=dom0_driver.o
+
ifdef CONFIG_SLIRP
CPPFLAGS+=-I$(SRC_PATH)/slirp
SLIRP_OBJS=cksum.o if.o ip_icmp.o ip_input.o ip_output.o \
diff -r 810d8c3ac992 tools/ioemu/dom0_driver.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/dom0_driver.c Fri May 09 16:47:04 2008 +0100
@@ -0,0 +1,172 @@
+/*
+ * QEMU dom0 /dev/input driver
+ *
+ * Copyright (c) 2008 Citrix Systems
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "vl.h"
+
+#include <sys/types.h>
+#include <linux/input.h>
+#include <linux/kd.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#define EVENT_PATH "/dev/input/event"
+
+struct dom0_driver
+{
+ int *event_fds;
+ int event_nb;
+ int mouse_button_state;
+};
+
+static struct dom0_driver driver;
+
+static void dom0_update(DisplayState *ds, int x, int y, int w, int h)
+{
+}
+
+static void dom0_resize(DisplayState *ds, int w, int h, int linesize)
+{
+}
+
+static void dom0_refresh(DisplayState *ds)
+{
+}
+
+static void dom0_read(void *opaque)
+{
+ struct input_event event[5];
+ int i = 0;
+ int read_sz = 0;
+ int fd = *(int *)opaque;
+
+ read_sz = read(fd, event, sizeof (event));
+ for (i = 0; i < read_sz / (sizeof (struct input_event)); i++)
+ {
+ if (event[i].type == EV_KEY)
+ {
+ if (event[i].code >= BTN_MOUSE)
+ {
+ /* Mouse Key */
+ int type = 0;
+
+ switch(event[i].code)
+ {
+ case BTN_LEFT: type = MOUSE_EVENT_LBUTTON; break;
+ case BTN_RIGHT: type = MOUSE_EVENT_RBUTTON; break;
+ }
+
+ if (event[i].value)
+ driver.mouse_button_state |= type;
+ else
+ driver.mouse_button_state &= ~type;
+ kbd_mouse_event(0, 0, 0, driver.mouse_button_state);
+ }
+ else
+ {
+ /* Keyboard key */
+ if (event[i].value == 1)
+ kbd_put_keycode(event[i].code | 0x80);
+ else
+ kbd_put_keycode(event[i].code & 0x7f);
+ }
+ }
+
+ if (event[i].type == EV_REL)
+ {
+ /* Mouse motion */
+ int x = 0, y = 0, z = 0;
+
+ switch (event[i].code)
+ {
+ case REL_X : x = event[i].value; break;
+ case REL_Y : y = event[i].value; break;
+ case REL_WHEEL : z = event[i].value; break;
+ }
+
+ kbd_mouse_event(x, y, z, driver.mouse_button_state);
+ }
+ }
+}
+
+static void dom0_driver_event_init()
+{
+ char dev_name[strlen(EVENT_PATH) + 3];
+ int fd = -1;
+ int i = 0;
+
+ do
+ {
+ snprintf(dev_name, sizeof (dev_name), "%s%d", EVENT_PATH, i++);
+ if ((fd = open(dev_name, O_RDONLY)) == -1)
+ return;
+ printf("Using %s\n", dev_name);
+
+ if (ioctl(fd, EVIOCGRAB, 1) == -1)
+ {
+ close(fd);
+ continue;
+ }
+
+ if (!(driver.event_fds = realloc(driver.event_fds,
+ (driver.event_nb + 1) * sizeof
(int))))
+ {
+ fprintf(stderr, "dom0_driver: memory allocation failed\n");
+ exit(1);
+ }
+
+ driver.event_fds[driver.event_nb] = fd;
+ qemu_set_fd_handler(fd, dom0_read, NULL,
+ &driver.event_fds[driver.event_nb]);
+ driver.event_nb++;
+ }
+ while (1);
+}
+
+static void dom0_driver_cleanup(void)
+{
+ free(driver.event_fds);
+}
+
+void dom0_driver_init(DisplayState *ds)
+{
+ memset(&driver, 0, sizeof (driver));
+
+ dom0_driver_event_init();
+
+ ds->data = NULL;
+ ds->linesize = 0;
+ ds->depth = 0;
+ ds->dpy_update = dom0_update;
+ ds->dpy_resize = dom0_resize;
+ ds->dpy_colourdepth = NULL;
+ ds->dpy_refresh = dom0_refresh;
+
+ atexit(dom0_driver_cleanup);
+}
diff -r 810d8c3ac992 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c Thu May 08 16:58:33 2008 +0100
+++ b/tools/ioemu/hw/pc.c Fri May 09 16:47:04 2008 +0100
@@ -814,6 +814,19 @@ static void pc_init1(uint64_t ram_size,
CPUState *env;
NICInfo *nd;
int rc;
+#ifdef CONFIG_DM
+ unsigned long vga_pt_enabled = 0;
+#endif /* CONFIG_DM */
+
+#ifdef CONFIG_DM
+ if (xc_get_hvm_param(xc_handle, domid,
+ HVM_PARAM_VGA_PT_ENABLED, &vga_pt_enabled))
+ {
+ fprintf(stderr, "vga passthrough : xc_get_hvm_param failed\n");
+ exit(1);
+ }
+
+#endif /* CONFIG_DM */
linux_boot = (kernel_filename != NULL);
@@ -862,12 +875,18 @@ static void pc_init1(uint64_t ram_size,
}
/* VGA BIOS load */
- if (cirrus_vga_enabled) {
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_CIRRUS_FILENAME);
- } else {
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
+#ifdef CONFIG_DM
+ if (!vga_pt_enabled)
+#endif /* CONFIG_DM */
+ {
+ fprintf(stderr, "Load qemu pci vga\n");
+ if (cirrus_vga_enabled) {
+ snprintf(buf, sizeof(buf), "%s/%s", bios_dir,
VGABIOS_CIRRUS_FILENAME);
+ } else {
+ snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
+ }
+ ret = load_image(buf, phys_ram_base + vga_bios_offset);
}
- ret = load_image(buf, phys_ram_base + vga_bios_offset);
#endif /* !NOBIOS */
/* setup basic memory access */
@@ -925,22 +944,27 @@ static void pc_init1(uint64_t ram_size,
register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);
- if (cirrus_vga_enabled) {
- if (pci_enabled) {
- pci_cirrus_vga_init(pci_bus,
- ds, NULL, ram_size,
- vga_ram_size);
+#ifdef CONFIG_DM
+ if (!vga_pt_enabled)
+#endif /* CONFIG_DM */
+ {
+ if (cirrus_vga_enabled) {
+ if (pci_enabled) {
+ pci_cirrus_vga_init(pci_bus,
+ ds, NULL, ram_size,
+ vga_ram_size);
+ } else {
+ isa_cirrus_vga_init(ds, NULL, ram_size,
+ vga_ram_size);
+ }
} else {
- isa_cirrus_vga_init(ds, NULL, ram_size,
- vga_ram_size);
- }
- } else {
- if (pci_enabled) {
- pci_vga_init(pci_bus, ds, NULL, ram_size,
- vga_ram_size, 0, 0);
- } else {
- isa_vga_init(ds, NULL, ram_size,
- vga_ram_size);
+ if (pci_enabled) {
+ pci_vga_init(pci_bus, ds, NULL, ram_size,
+ vga_ram_size, 0, 0);
+ } else {
+ isa_vga_init(ds, NULL, ram_size,
+ vga_ram_size);
+ }
}
}
diff -r 810d8c3ac992 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Thu May 08 16:58:33 2008 +0100
+++ b/tools/ioemu/vl.c Fri May 09 16:47:04 2008 +0100
@@ -179,6 +179,9 @@ int opengl_enabled = 1;
#else
int opengl_enabled = 0;
#endif
+#ifdef CONFIG_DM
+int dom0_input = 0;
+#endif /* CONFIG_DM */
int no_quit = 0;
CharDriverState *serial_hds[MAX_SERIAL_PORTS];
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
@@ -6486,8 +6489,9 @@ void help(void)
"-no-quit disable SDL window close capability\n"
#endif
#ifdef CONFIG_OPENGL
- "-disable-opengl disable OpenGL rendering, using SDL"
-#endif
+ "-disable-opengl disable OpenGL rendering, using SDL\n"
+#endif
+ "-dom0-input enable dom0 controling qemu\n"
#ifdef TARGET_I386
"-no-fd-bootchk disable boot signature checking for floppy disks\n"
#endif
@@ -6667,6 +6671,9 @@ enum {
QEMU_OPTION_full_screen,
QEMU_OPTION_no_quit,
QEMU_OPTION_disable_opengl,
+#ifdef CONFIG_DM
+ QEMU_OPTION_dom0_input,
+#endif /* CONFIG_DM */
QEMU_OPTION_pidfile,
QEMU_OPTION_no_kqemu,
QEMU_OPTION_kernel_kqemu,
@@ -6765,6 +6772,7 @@ const QEMUOption qemu_options[] = {
{ "no-quit", 0, QEMU_OPTION_no_quit },
#endif
{ "disable-opengl", 0, QEMU_OPTION_disable_opengl },
+ { "dom0-input", 0, QEMU_OPTION_dom0_input },
{ "pidfile", HAS_ARG, QEMU_OPTION_pidfile },
{ "win2k-hack", 0, QEMU_OPTION_win2k_hack },
{ "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice },
@@ -7516,6 +7524,11 @@ int main(int argc, char **argv)
case QEMU_OPTION_disable_opengl:
opengl_enabled = 0;
break;
+#ifdef CONFIG_DM
+ case QEMU_OPTION_dom0_input:
+ dom0_input = 1;
+ break;
+#endif /* CONFIG_DM */
case QEMU_OPTION_pidfile:
create_pidfile(optarg);
break;
@@ -7823,12 +7836,18 @@ int main(int argc, char **argv)
init_ioports();
/* terminal init */
+
#ifdef CONFIG_STUBDOM
if (xenfb_pv_display_init(ds) == 0) {
} else
#endif
if (nographic) {
+#ifdef CONFIG_DM
+ if (dom0_input == 1)
+ dom0_driver_init(ds);
+#else
dumb_display_init(ds);
+#endif /* CONFIG_DM */
} else if (vnc_display != NULL || vncunused != 0) {
int vnc_display_port;
char password[20];
diff -r 810d8c3ac992 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h Thu May 08 16:58:33 2008 +0100
+++ b/tools/ioemu/vl.h Fri May 09 16:47:04 2008 +0100
@@ -997,6 +997,9 @@ void do_info_vnc(void);
void do_info_vnc(void);
int vnc_start_viewer(int port);
+/* dom0_driver.c */
+void dom0_driver_init(DisplayState *ds);
+
/* x_keymap.c */
extern uint8_t _translate_keycode(const int key);
diff -r 810d8c3ac992 tools/libxc/xc_hvm_build.c
--- a/tools/libxc/xc_hvm_build.c Thu May 08 16:58:33 2008 +0100
+++ b/tools/libxc/xc_hvm_build.c Fri May 09 16:47:04 2008 +0100
@@ -152,9 +152,134 @@ static int loadelfimage(
return rc;
}
+static int linux_get_vgabios(int xc_handle,
+ unsigned char *buf,
+ int len)
+{
+ char buff[1024];
+ FILE *fd;
+ int mem;
+ char *end_ptr;
+ uint32_t start, end, size;
+
+ if (!(fd = fopen("/proc/iomem", "r")))
+ return 0;
+
+ while (fgets(buff, 1024, fd))
+ if (strstr(buff, "Video ROM"))
+ break;
+
+ if (feof(fd) || ferror(fd))
+ {
+ fclose(fd);
+ return 0;
+ }
+
+ fclose(fd);
+ start = strtol(buff, &end_ptr, 16);
+ end = strtol(end_ptr + 1, NULL, 16);
+ size = end - start + 1;
+
+ if ((mem = open("/dev/mem", O_RDONLY)) < 0)
+ return 0;
+
+ if (start != lseek(mem, start, SEEK_SET))
+ {
+ close(mem);
+ return 0;
+ }
+
+ if (size != read(mem, buf, size))
+ size = 0;
+ close(mem);
+ return size;
+}
+
+static int linux_map_vga_ioport(int xc_handler,
+ uint32_t dom)
+{
+ FILE *fd = NULL;
+ char buff[256];
+ uint32_t start, end;
+ char *buff_end = NULL;
+
+ if (!(fd = fopen("/proc/ioports", "r")))
+ return -1;
+
+ while (fgets(buff, 256, fd))
+ if (strstr(buff, "vga"))
+ break;
+
+ if (feof(fd) || ferror(fd))
+ {
+ fclose(fd);
+ return -1;
+ }
+
+ fclose(fd);
+
+ start = strtol(buff, &buff_end, 16);
+ end = strtol(buff_end + 1, NULL, 16);
+
+ return xc_domain_ioport_mapping(xc_handler, dom,
+ start, start, end - start + 1, 1);
+}
+
+static int setup_vga_pt(int xc_handle,
+ uint32_t dom,
+ uint32_t paddr,
+ struct hvm_info_table *hvm_info)
+{
+ int rc = 0;
+ unsigned char *bios = NULL;
+ int bios_size = 0;
+ char *va_bios = NULL;
+ uint32_t pfn = 0;
+
+ /* Allocated 128K for the vga bios */
+ if (!(bios = malloc(128 * 1024)))
+ return -1;
+
+ /* Align paddr on the first next page */
+ pfn = (paddr >> XC_PAGE_SHIFT) + 1;
+
+ bios_size = linux_get_vgabios(xc_handle, bios, 128 * 1024);
+ if (bios_size == 0)
+ {
+ rc = -1;
+ goto error;
+ }
+
+ va_bios = xc_map_foreign_range(xc_handle, dom,
+ bios_size + bios_size % XC_PAGE_SIZE,
+ PROT_READ | PROT_WRITE, pfn);
+ if (!va_bios)
+ {
+ rc = -1;
+ goto error;
+ }
+
+ memcpy(va_bios, bios, bios_size);
+ hvm_info->vga_bios_paddr = pfn << XC_PAGE_SHIFT;
+ hvm_info->vga_bios_size = bios_size;
+ munmap(va_bios, bios_size + bios_size % XC_PAGE_SIZE);
+
+ rc |= xc_domain_memory_mapping(xc_handle, dom,
+ 0xa0000 >> XC_PAGE_SHIFT,
+ 0xa0000 >> XC_PAGE_SHIFT,
+ (0xc0000 - 0xa0000) >> XC_PAGE_SHIFT,
+ 1);
+ rc |= linux_map_vga_ioport(xc_handle, dom);
+
+error:
+ free(bios);
+ return rc;
+}
+
static int setup_guest(int xc_handle,
uint32_t dom, int memsize,
- char *image, unsigned long image_size)
+ char *image, unsigned long image_size,
+ struct hvm_info_table *hvm_info)
{
xen_pfn_t *page_array = NULL;
unsigned long i, nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT);
@@ -167,6 +292,7 @@ static int setup_guest(int xc_handle,
uint64_t v_start, v_end;
int rc;
xen_capabilities_info_t caps;
+ unsigned long vga_pt_enabled = 0;
/* An HVM guest must be initialised with at least 2MB memory. */
if ( memsize < 2 )
@@ -314,6 +440,14 @@ static int setup_guest(int xc_handle,
}
free(page_array);
+
+ /* Setup VGA pass through */
+ if ( xc_get_hvm_param(xc_handle, dom,
+ HVM_PARAM_VGA_PT_ENABLED, &vga_pt_enabled) )
+ return -1;
+ if ( vga_pt_enabled )
+ return setup_vga_pt(xc_handle, dom, elf.pend, hvm_info);
+
return 0;
error_out:
@@ -325,7 +459,8 @@ static int xc_hvm_build_internal(int xc_
uint32_t domid,
int memsize,
char *image,
- unsigned long image_size)
+ unsigned long image_size,
+ struct hvm_info_table *hvm_info)
{
if ( (image == NULL) || (image_size == 0) )
{
@@ -333,7 +468,7 @@ static int xc_hvm_build_internal(int xc_
return -1;
}
- return setup_guest(xc_handle, domid, memsize, image, image_size);
+ return setup_guest(xc_handle, domid, memsize, image, image_size, hvm_info);
}
static inline int is_loadable_phdr(Elf32_Phdr *phdr)
@@ -348,7 +483,8 @@ int xc_hvm_build(int xc_handle,
int xc_hvm_build(int xc_handle,
uint32_t domid,
int memsize,
- const char *image_name)
+ const char *image_name,
+ struct hvm_info_table *hvm_info)
{
char *image;
int sts;
@@ -358,7 +494,8 @@ int xc_hvm_build(int xc_handle,
((image = xc_read_image(image_name, &image_size)) == NULL) )
return -1;
- sts = xc_hvm_build_internal(xc_handle, domid, memsize, image, image_size);
+ sts = xc_hvm_build_internal(xc_handle, domid, memsize,
+ image, image_size, hvm_info);
free(image);
@@ -372,7 +509,8 @@ int xc_hvm_build_mem(int xc_handle,
uint32_t domid,
int memsize,
const char *image_buffer,
- unsigned long image_size)
+ unsigned long image_size,
+ struct hvm_info_table *hvm_info)
{
int sts;
unsigned long img_len;
@@ -394,7 +532,7 @@ int xc_hvm_build_mem(int xc_handle,
}
sts = xc_hvm_build_internal(xc_handle, domid, memsize,
- img, img_len);
+ img, img_len, hvm_info);
/* xc_inflate_buffer may return the original buffer pointer (for
for already inflated buffers), so exercise some care in freeing */
diff -r 810d8c3ac992 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Thu May 08 16:58:33 2008 +0100
+++ b/tools/libxc/xenctrl.h Fri May 09 16:47:04 2008 +0100
@@ -30,6 +30,7 @@
#include <xen/xsm/acm.h>
#include <xen/xsm/acm_ops.h>
#include <xen/xsm/flask_op.h>
+#include <xen/hvm/params.h>
#ifdef __ia64__
#define XC_PAGE_SHIFT 14
diff -r 810d8c3ac992 tools/libxc/xenguest.h
--- a/tools/libxc/xenguest.h Thu May 08 16:58:33 2008 +0100
+++ b/tools/libxc/xenguest.h Fri May 09 16:47:04 2008 +0100
@@ -6,6 +6,8 @@
* Copyright (c) 2003-2004, K A Fraser.
*/
+#include <xen/hvm/hvm_info_table.h>
+
#ifndef XENGUEST_H
#define XENGUEST_H
@@ -13,7 +15,6 @@
#define XCFLAGS_DEBUG 2
#define XCFLAGS_HVM 4
#define XCFLAGS_STDVGA 8
-
/**
* This function will save a running domain.
@@ -128,12 +129,14 @@ int xc_hvm_build(int xc_handle,
int xc_hvm_build(int xc_handle,
uint32_t domid,
int memsize,
- const char *image_name);
+ const char *image_name,
+ struct hvm_info_table *hvm_info);
int xc_hvm_build_mem(int xc_handle,
uint32_t domid,
int memsize,
const char *image_buffer,
- unsigned long image_size);
+ unsigned long image_size,
+ struct hvm_info_table *hvm_info);
#endif /* XENGUEST_H */
diff -r 810d8c3ac992 tools/libxc/xg_private.c
--- a/tools/libxc/xg_private.c Thu May 08 16:58:33 2008 +0100
+++ b/tools/libxc/xg_private.c Fri May 09 16:47:04 2008 +0100
@@ -193,7 +193,8 @@ __attribute__((weak))
int xc_hvm_build(int xc_handle,
uint32_t domid,
int memsize,
- const char *image_name)
+ const char *image_name,
+ struct hvm_info_table *hvm_info)
{
errno = ENOSYS;
return -1;
diff -r 810d8c3ac992 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Thu May 08 16:58:33 2008 +0100
+++ b/tools/python/xen/lowlevel/xc/xc.c Fri May 09 16:47:04 2008 +0100
@@ -721,22 +721,28 @@ static PyObject *pyxc_hvm_build(XcObject
{
uint32_t dom;
#if !defined(__ia64__)
+ struct hvm_info_table hvm_info;
struct hvm_info_table *va_hvm;
uint8_t *va_map, sum;
int i;
#endif
char *image;
- int memsize, vcpus = 1, acpi = 0, apic = 1;
+ int memsize, vcpus = 1, acpi = 0, apic = 1, vga_pt = 0;
static char *kwd_list[] = { "domid",
"memsize", "image", "vcpus", "acpi",
- "apic", NULL };
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iii", kwd_list,
+ "apic", "vga_pt", NULL };
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiii", kwd_list,
&dom, &memsize,
- &image, &vcpus, &acpi, &apic) )
+ &image, &vcpus, &acpi, &apic, &vga_pt) )
return NULL;
- if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 )
+ if ( xc_set_hvm_param(self->xc_handle, dom,
+ HVM_PARAM_VGA_PT_ENABLED, vga_pt) )
+ return pyxc_error_to_exception();
+
+ memset(&hvm_info, 0, sizeof(hvm_info));
+ if ( xc_hvm_build(self->xc_handle, dom, memsize, image, &hvm_info) != 0 )
return pyxc_error_to_exception();
#if !defined(__ia64__)
@@ -747,7 +753,7 @@ static PyObject *pyxc_hvm_build(XcObject
if ( va_map == NULL )
return PyErr_SetFromErrno(xc_error_obj);
va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
- memset(va_hvm, 0, sizeof(*va_hvm));
+ memcpy(va_hvm, &hvm_info, sizeof (*va_hvm));
strncpy(va_hvm->signature, "HVM INFO", 8);
va_hvm->length = sizeof(struct hvm_info_table);
va_hvm->acpi_enabled = acpi;
diff -r 810d8c3ac992 tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Thu May 08 16:58:33 2008 +0100
+++ b/tools/python/xen/xend/XendConfig.py Fri May 09 16:47:04 2008 +0100
@@ -160,6 +160,7 @@ XENAPI_PLATFORM_CFG_TYPES = {
'vhpt': int,
'guest_os_type': str,
'hap': int,
+ 'vga_passthrough' : int,
}
# Xen API console 'other_config' keys.
diff -r 810d8c3ac992 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Thu May 08 16:58:33 2008 +0100
+++ b/tools/python/xen/xend/image.py Fri May 09 16:47:04 2008 +0100
@@ -240,6 +240,8 @@ class ImageHandler:
vnc_config = {}
has_vnc = int(vmConfig['platform'].get('vnc', 0)) != 0
has_sdl = int(vmConfig['platform'].get('sdl', 0)) != 0
+ has_vga_passthrough = int(vmConfig['platform'].get('vga_passthrough',
0)) != 0;
+
opengl = 1
for dev_uuid in vmConfig['console_refs']:
dev_type, dev_info = vmConfig['devices'][dev_uuid]
@@ -260,7 +262,7 @@ class ImageHandler:
ret.append("-k")
ret.append(keymap)
- if has_vnc:
+ if has_vnc and not has_vga_passthrough:
if not vnc_config:
for key in ('vncunused', 'vnclisten', 'vncdisplay',
'vncpasswd'):
@@ -310,6 +312,10 @@ class ImageHandler:
if int(vmConfig['platform'].get('monitor', 0)) != 0:
ret = ret + ['-monitor', 'vc']
+
+ if has_vga_passthrough:
+ ret.append('-dom0-input');
+
return ret
def getDeviceModelArgs(self, restore = False):
@@ -536,6 +542,7 @@ class HVMImageHandler(ImageHandler):
self.apic = int(vmConfig['platform'].get('apic', 0))
self.acpi = int(vmConfig['platform'].get('acpi', 0))
self.guest_os_type = vmConfig['platform'].get('guest_os_type')
+ self.vga_pt = int(vmConfig['platform'].get('vga_passthrough', 0))
self.vmConfig = vmConfig
@@ -661,6 +668,7 @@ class HVMImageHandler(ImageHandler):
mem_mb = self.getRequiredInitialReservation() / 1024
+ log.debug(self.vmConfig)
log.debug("domid = %d", self.vm.getDomid())
log.debug("image = %s", self.loader)
log.debug("store_evtchn = %d", store_evtchn)
@@ -668,13 +676,15 @@ class HVMImageHandler(ImageHandler):
log.debug("vcpus = %d", self.vm.getVCpuCount())
log.debug("acpi = %d", self.acpi)
log.debug("apic = %d", self.apic)
+ log.debug("vga_pt = %d", self.vga_pt)
rc = xc.hvm_build(domid = self.vm.getDomid(),
image = self.loader,
memsize = mem_mb,
vcpus = self.vm.getVCpuCount(),
acpi = self.acpi,
- apic = self.apic)
+ apic = self.apic,
+ vga_pt = self.vga_pt)
rc['notes'] = { 'SUSPEND_CANCEL': 1 }
rc['store_mfn'] = xc.hvm_get_param(self.vm.getDomid(),
diff -r 810d8c3ac992 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Thu May 08 16:58:33 2008 +0100
+++ b/tools/python/xen/xm/create.py Fri May 09 16:47:04 2008 +0100
@@ -557,6 +557,10 @@ gopts.var('cpuid_check', val="IN[,SIN]:e
fn=append_value, default=[],
use="""Cpuid check description.""")
+gopts.var('vga_passthrough', val='VGA_PT',
+ fn=set_int, default=None,
+ use="Enable the passthrough for the graphic card.")
+
def err(msg):
"""Print an error to stderr and exit.
"""
@@ -763,7 +767,8 @@ def configure_hvm(config_image, vals):
'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten',
'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor',
'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci', 'hpet',
- 'guest_os_type', 'hap', 'opengl', 'cpuid', 'cpuid_check']
+ 'guest_os_type', 'hap', 'opengl', 'cpuid', 'cpuid_check',
+ 'vga_passthrough' ]
for a in args:
if a in vals.__dict__ and vals.__dict__[a] is not None:
diff -r 810d8c3ac992 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Thu May 08 16:58:33 2008 +0100
+++ b/xen/arch/x86/hvm/hvm.c Fri May 09 16:47:04 2008 +0100
@@ -310,7 +310,8 @@ int hvm_domain_initialise(struct domain
if ( rc != 0 )
goto fail1;
- stdvga_init(d);
+ if ( !d->arch.hvm_domain.params[HVM_PARAM_VGA_PT_ENABLED] )
+ stdvga_init(d);
hvm_init_ioreq_page(d, &d->arch.hvm_domain.ioreq);
hvm_init_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
diff -r 810d8c3ac992 xen/include/public/hvm/hvm_info_table.h
--- a/xen/include/public/hvm/hvm_info_table.h Thu May 08 16:58:33 2008 +0100
+++ b/xen/include/public/hvm/hvm_info_table.h Fri May 09 16:47:04 2008 +0100
@@ -36,6 +36,9 @@ struct hvm_info_table {
uint8_t acpi_enabled;
uint8_t apic_mode;
uint32_t nr_vcpus;
+ uint32_t vga_bios_paddr;
+ uint32_t vga_bios_size;
+
};
#endif /* __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__ */
diff -r 810d8c3ac992 xen/include/public/hvm/params.h
--- a/xen/include/public/hvm/params.h Thu May 08 16:58:33 2008 +0100
+++ b/xen/include/public/hvm/params.h Fri May 09 16:47:04 2008 +0100
@@ -90,6 +90,9 @@
/* Device Model domain, defaults to 0. */
#define HVM_PARAM_DM_DOMAIN 13
-#define HVM_NR_PARAMS 14
+/* Boolean : VGA passthrough */
+#define HVM_PARAM_VGA_PT_ENABLED 14
+
+#define HVM_NR_PARAMS 15
#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|