[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] Pass-through a graphic card
I new version (again). Here the change for this version : - No more modification of the hvm_info_table. - Creatation of a SCRATCH zone for hvmloader : 0x1000.- Copy directly the VGABIOS at the right place (0xC0000) into the guest memory. - Detect which graphic card are present in pci_setup(). - Remove the function cirrus_check - Add the support for some special keys for the dom0 driver. --- This patch is for pass-through the principal graphic card to a hvm guest. This is what is done inside :- We map the VGA frame buffer into the guest's memory (0xa0000 -> 0xbffff) - We get the vga bios address into the guest memory. Etherboot has been moved to 0xD0000 to let enough space to load the dom0 vgabios (it could be pretty big). - Map the vga ioport 0x03c0 -> 0x03df.- Then we start qemu with the new option -dom0-driver to have the dom0's keyboard and the mouse redirected into the guest. Signed-off-by: Jean Guyader <jean.guyader@xxxxxxxxxxxxx> -- Jean Guyader diff -r f65906f262f9 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Fri May 16 09:31:03 2008 +0100 +++ b/tools/firmware/hvmloader/config.h Fri May 16 09:35:12 2008 +0100 @@ -23,11 +23,12 @@ /* 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 #define ACPI_PHYSICAL_ADDRESS 0x000EA000 #define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000 +#define SCRATCH_PHYSICAL_ADDRESS 0x00010000 #endif /* __HVMLOADER_CONFIG_H__ */ diff -r f65906f262f9 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Fri May 16 09:31:03 2008 +0100 +++ b/tools/firmware/hvmloader/hvmloader.c Fri May 16 09:35:12 2008 +0100 @@ -103,12 +103,8 @@ void create_mp_tables(void); void create_mp_tables(void); int hvm_write_smbios_tables(void); -static int -cirrus_check(void) -{ - outw(0x3C4, 0x9206); - return inb(0x3C5) == 0x12; -} +static int cirrus_checked = 0; +static int stdvga_checked = 0; static void init_hypercalls(void) @@ -165,7 +161,7 @@ static void pci_setup(void) /* Create a list of device BARs in descending order of size. */ struct bars { uint32_t devfn, bar_reg, bar_sz; - } *bars = (struct bars *)0xc0000; + } *bars = (struct bars *)SCRATCH_PHYSICAL_ADDRESS; unsigned int i, nr_bars = 0; /* Program PCI-ISA bridge with appropriate link routes. */ @@ -190,6 +186,15 @@ static void pci_setup(void) device_id = pci_readw(devfn, PCI_DEVICE_ID); if ( (vendor_id == 0xffff) && (device_id == 0xffff) ) continue; + + /* Detect emulated graphic card */ + if ( class == 0x300 ) + { + if ( (vendor_id == 0x1013) && (device_id == 0xb8) ) + cirrus_checked = 1; + if ( (vendor_id == 0x1234) && (device_id == 0x1111) ) + stdvga_checked = 1; + } ASSERT((devfn != PCI_ISA_DEVFN) || ((vendor_id == 0x8086) && (device_id == 0x7000))); @@ -464,20 +469,22 @@ int main(void) if ( (get_vcpu_nr() > 1) || get_apic_mode() ) create_mp_tables(); - if ( cirrus_check() ) + if ( cirrus_checked ) { printf("Loading Cirrus VGABIOS ...\n"); memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, vgabios_cirrusvga, sizeof(vgabios_cirrusvga)); vgabios_sz = sizeof(vgabios_cirrusvga); } - else + else if ( stdvga_checked ) { printf("Loading Standard VGABIOS ...\n"); memcpy((void *)VGABIOS_PHYSICAL_ADDRESS, vgabios_stdvga, sizeof(vgabios_stdvga)); vgabios_sz = sizeof(vgabios_stdvga); } + else + printf("VGABIOS must already be there ...\n"); etherboot_sz = scan_etherboot_nic((void*)ETHERBOOT_PHYSICAL_ADDRESS); diff -r f65906f262f9 tools/firmware/hvmloader/smbios.c --- a/tools/firmware/hvmloader/smbios.c Fri May 16 09:31:03 2008 +0100 +++ b/tools/firmware/hvmloader/smbios.c Fri May 16 09:35:12 2008 +0100 @@ -217,15 +217,16 @@ hvm_write_smbios_tables(void) xen_version_str[sizeof(xen_version_str)-1] = '\0'; - /* NB. 0xC0000 is a safe large memory area for scratch. */ - len = write_smbios_tables((void *)0xC0000, + /* SCRATCH_PHYSICAL_ADDRESS is a safe large memory area for scratch. */ + len = write_smbios_tables((void *)SCRATCH_PHYSICAL_ADDRESS, get_vcpu_nr(), get_memsize(), uuid, xen_version_str, xen_major_version, xen_minor_version); if ( len > SMBIOS_MAXIMUM_SIZE ) goto error_out; /* Okay, not too large: copy out of scratch to final location. */ - memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, (void *)0xC0000, len); + memcpy((void *)SMBIOS_PHYSICAL_ADDRESS, + (void *)SCRATCH_PHYSICAL_ADDRESS, len); return len; diff -r f65906f262f9 tools/ioemu/Makefile.target --- a/tools/ioemu/Makefile.target Fri May 16 09:31:03 2008 +0100 +++ b/tools/ioemu/Makefile.target Fri May 16 09:35:12 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 f65906f262f9 tools/ioemu/dom0_driver.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/ioemu/dom0_driver.c Fri May 16 09:35:12 2008 +0100 @@ -0,0 +1,204 @@ +/* + * 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> +#include <string.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 */ + int code[2] = { event[i].code, -1 }; + int i = 0; + + switch (event[i].code) + { + case KEY_F11: *code = 0X57; break; /* F11 */ + case KEY_F12: *code = 0X58; break; /* F12 */ + case KEY_INSERT: *code = 0X52; break; + case KEY_HOME: *code = 0X47; break; + case KEY_PAGEUP: *code = 0X49; break; + case KEY_DELETE: *code = 0X53; break; + case KEY_END: *code = 0X4F; break; + case KEY_PAGEDOWN: *code = 0X51; break; + case KEY_UP: *code = 0X48; break; + case KEY_LEFT: *code = 0X4B; break; + case KEY_DOWN: *code = 0X50; break; + case KEY_RIGHT: *code = 0X4D; break; + case KEY_RIGHTALT: *code = 0xE0; code[1] = 0x38; break; + } + + for ( i = 0; i < 2; i++ ) + if (code[i] != -1) + switch (event[i].value) + { + case 0: + kbd_put_keycode(code[i] & 0x7f); + break; + case 1: + kbd_put_keycode(code[i] | 0x80); + break; + case 2: + kbd_put_keycode(code[i] | 0x80); + kbd_put_keycode(code[i] & 0x7f); + break; + } + } + } + + 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 f65906f262f9 tools/ioemu/hw/pc.c --- a/tools/ioemu/hw/pc.c Fri May 16 09:31:03 2008 +0100 +++ b/tools/ioemu/hw/pc.c Fri May 16 09:35:12 2008 +0100 @@ -43,6 +43,10 @@ static IOAPICState *ioapic; static IOAPICState *ioapic; #endif /* !CONFIG_DM */ static PCIDevice *i440fx_state; + +#ifdef CONFIG_DM +extern int dom0_input; +#endif /* CONFIG_DM */ static void ioport80_write(void *opaque, uint32_t addr, uint32_t data) { @@ -814,6 +818,9 @@ static void pc_init1(uint64_t ram_size, CPUState *env; NICInfo *nd; int rc; +#ifdef CONFIG_DM + unsigned long vga_pt_enabled = dom0_input; +#endif /* CONFIG_DM */ linux_boot = (kernel_filename != NULL); @@ -862,12 +869,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 +938,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 f65906f262f9 tools/ioemu/vl.c --- a/tools/ioemu/vl.c Fri May 16 09:31:03 2008 +0100 +++ b/tools/ioemu/vl.c Fri May 16 09:35:12 2008 +0100 @@ -177,6 +177,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; @@ -7828,7 +7841,12 @@ int main(int argc, char **argv) } 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 f65906f262f9 tools/ioemu/vl.h --- a/tools/ioemu/vl.h Fri May 16 09:31:03 2008 +0100 +++ b/tools/ioemu/vl.h Fri May 16 09:35:13 2008 +0100 @@ -1001,6 +1001,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 f65906f262f9 tools/libxc/xc_hvm_build.c --- a/tools/libxc/xc_hvm_build.c Fri May 16 09:31:03 2008 +0100 +++ b/tools/libxc/xc_hvm_build.c Fri May 16 09:35:13 2008 +0100 @@ -152,6 +152,52 @@ static int loadelfimage( if ( entries ) free(entries); + return rc; +} + +static int setup_vga_pt(int xc_handle, + uint32_t dom) +{ + int rc = 0; + unsigned char *bios = NULL; + int bios_size = 0; + char *va_bios = NULL; + uint32_t va_size = 0; + + /* Allocated 64K for the vga bios */ + if (!(bios = malloc(64 * 1024))) + return -1; + +#ifdef __linux__ + bios_size = xc_get_vgabios(bios, 64 * 1024); +#else + bios_size = 0; +#endif /* __linux__ */ + + va_size = bios_size + bios_size % XC_PAGE_SIZE; + if (bios_size == 0) + { + rc = -1; + goto error; + } + va_bios = xc_map_foreign_range(xc_handle, dom, va_size, + PROT_READ | PROT_WRITE, 0xC0); + if (!va_bios) + { + rc = -1; + goto error; + } + + memcpy(va_bios, bios, bios_size); + munmap(va_bios, va_size); + rc |= xc_domain_memory_mapping(xc_handle, dom, + 0xa0000 >> XC_PAGE_SHIFT, + 0xa0000 >> XC_PAGE_SHIFT, + (0xc0000 - 0xa0000) >> XC_PAGE_SHIFT, 1); + rc |= xc_domain_ioport_mapping(xc_handle, dom, + 0x3C0, 0x3C0, 32, 1); +error: + free(bios); return rc; } @@ -388,17 +434,20 @@ 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, + int vga_pt_enabled) { char *image; - int sts; + int sts = 0; unsigned long image_size; if ( (image_name == NULL) || ((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); + if ( vga_pt_enabled ) + sts |= setup_vga_pt(xc_handle, domid); free(image); diff -r f65906f262f9 tools/libxc/xc_linux.c --- a/tools/libxc/xc_linux.c Fri May 16 09:31:03 2008 +0100 +++ b/tools/libxc/xc_linux.c Fri May 16 09:35:13 2008 +0100 @@ -518,6 +518,30 @@ int xc_gnttab_set_max_grants(int xcg_han return 0; } +int xc_get_vgabios(unsigned char *buf, + int len) +{ + int mem; + uint32_t start, end, size; + + start = 0xC0000; + end = 0xCAFFF; + size = end - start + 1; + if (len < size) + return 0; + 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; +} + /* * Local variables: * mode: C diff -r f65906f262f9 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Fri May 16 09:31:03 2008 +0100 +++ b/tools/libxc/xenctrl.h Fri May 16 09:35:13 2008 +0100 @@ -138,6 +138,10 @@ int xc_waitdomain( int domain, int *status, int options); + +int xc_get_vgabios( + unsigned char *bios, + int len); #endif /* __linux__ */ diff -r f65906f262f9 tools/libxc/xenguest.h --- a/tools/libxc/xenguest.h Fri May 16 09:31:03 2008 +0100 +++ b/tools/libxc/xenguest.h Fri May 16 09:35:13 2008 +0100 @@ -128,7 +128,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, + int vga_pt_enabled); int xc_hvm_build_mem(int xc_handle, uint32_t domid, diff -r f65906f262f9 tools/libxc/xg_private.c --- a/tools/libxc/xg_private.c Fri May 16 09:31:03 2008 +0100 +++ b/tools/libxc/xg_private.c Fri May 16 09:35:13 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, + int vga_pt_enabled) { errno = ENOSYS; return -1; diff -r f65906f262f9 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Fri May 16 09:31:03 2008 +0100 +++ b/tools/python/xen/lowlevel/xc/xc.c Fri May 16 09:35:13 2008 +0100 @@ -726,17 +726,17 @@ static PyObject *pyxc_hvm_build(XcObject 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_hvm_build(self->xc_handle, dom, memsize, image, vga_pt) != 0 ) return pyxc_error_to_exception(); #if !defined(__ia64__) diff -r f65906f262f9 tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Fri May 16 09:31:03 2008 +0100 +++ b/tools/python/xen/xend/XendConfig.py Fri May 16 09:35:13 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 f65906f262f9 tools/python/xen/xend/image.py --- a/tools/python/xen/xend/image.py Fri May 16 09:31:03 2008 +0100 +++ b/tools/python/xen/xend/image.py Fri May 16 09:35:13 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 @@ -668,13 +675,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 f65906f262f9 tools/python/xen/xm/create.py --- a/tools/python/xen/xm/create.py Fri May 16 09:31:03 2008 +0100 +++ b/tools/python/xen/xm/create.py Fri May 16 09:35:13 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. """ @@ -765,7 +769,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: _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |