[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] Pass-through a graphic card
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |