[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] Pass-through a graphic card
Hi folk, 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 from /dev/iomem and we put it at the end of hvmloader. Etherboot has been moved to 0xD0000 to let enough space to load the dom0 vgabios (it could be pretty big). - Map the vga ioport using /dev/ioports. - We disable the vga code into xen, hvm.c:313- Then we start qemu with the new option -enable-dom0 to have the dom0's keyboard and the mouse redirected into the guest. This patch work only with the principal graphic card and you must have a box with vt-d. Signed-off-by: Jean Guyader <jean.guyader@xxxxxxxxxxxxx> --- Here an example of how to enable the feature : -------------- kernel = "/usr/lib/xen/boot/hvmloader" builder='hvm' memory = 512 name = "winxp" vif=[ 'type=ioemu,bridge=eth0,mac=00:16:3E:2E:26:BE' ] disk=['file:/mnt/img/winxp/disk.img,ioemu:hda,w'] boot="c" vnc=0 timer_mode=2 pci = [ '0a:01.0' ] vga_pass through=1 --------------Be careful, vnc must be at 0. 0a:01.0 is the pci id of my graphic card, of course it must be hide with pciback. Thanks for your comments. -- 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 11:53:08 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 11:53:08 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 11:53:08 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 11:53:08 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 11:53:08 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/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 11:53:08 2008 +0100 @@ -814,6 +814,13 @@ 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 + xc_get_hvm_param(xc_handle, domid, HVM_PARAM_VGA_PT_ENABLED, &vga_pt_enabled); +#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 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 11:53:08 2008 +0100 @@ -179,6 +179,9 @@ int opengl_enabled = 1; #else int opengl_enabled = 0; #endif +#ifdef CONFIG_DM +int dom0_control = 0; +#endif /* CONFIG_DM */ int no_quit = 0; CharDriverState *serial_hds[MAX_SERIAL_PORTS]; CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; @@ -4455,6 +4458,7 @@ static void dumb_resize(DisplayState *ds static void dumb_refresh(DisplayState *ds) { + printf("dumb_refresh\n"); vga_hw_update(); } @@ -6486,8 +6490,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 + "-enable-dom0 enable dom0 controling qemu\n" #ifdef TARGET_I386 "-no-fd-bootchk disable boot signature checking for floppy disks\n" #endif @@ -6667,6 +6672,9 @@ enum { QEMU_OPTION_full_screen, QEMU_OPTION_no_quit, QEMU_OPTION_disable_opengl, +#ifdef CONFIG_DM + QEMU_OPTION_dom0_control, +#endif /* CONFIG_DM */ QEMU_OPTION_pidfile, QEMU_OPTION_no_kqemu, QEMU_OPTION_kernel_kqemu, @@ -6765,6 +6773,7 @@ const QEMUOption qemu_options[] = { { "no-quit", 0, QEMU_OPTION_no_quit }, #endif { "disable-opengl", 0, QEMU_OPTION_disable_opengl }, + { "enable-dom0", 0, QEMU_OPTION_dom0_control }, { "pidfile", HAS_ARG, QEMU_OPTION_pidfile }, { "win2k-hack", 0, QEMU_OPTION_win2k_hack }, { "usbdevice", HAS_ARG, QEMU_OPTION_usbdevice }, @@ -7516,6 +7525,11 @@ int main(int argc, char **argv) case QEMU_OPTION_disable_opengl: opengl_enabled = 0; break; +#ifdef CONFIG_DM + case QEMU_OPTION_dom0_control: + dom0_control = 1; + break; +#endif /* CONFIG_DM */ case QEMU_OPTION_pidfile: create_pidfile(optarg); break; @@ -7823,12 +7837,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_control == 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]; @@ -7842,7 +7862,9 @@ int main(int argc, char **argv) vnc_start_viewer(vnc_display_port); #endif xenstore_write_vncport(vnc_display_port); - } else { + } + else + { #if defined(CONFIG_SDL) sdl_display_init(ds, full_screen, opengl_enabled); #elif defined(CONFIG_COCOA) 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 11:53:08 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 11:53:08 2008 +0100 @@ -152,9 +152,121 @@ static int loadelfimage( return rc; } +static int linux_get_vgabios(int xc_handle, + unsigned char *buf, + int len) +{ + char buff[1024]; + FILE *fd, *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)) + { + 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 = fopen("/dev/mem", "r"))) + return 0; + + fseek(mem, start, SEEK_SET); + fread(buf, 1, size, mem); + fclose(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)) + { + 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) + { + free(bios); + return -1; + } + + va_bios = xc_map_foreign_range(xc_handle, dom, 16 * XC_PAGE_SIZE, + PROT_READ | PROT_WRITE, pfn); + + 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, 16 * XC_PAGE_SIZE); + free(bios); + + rc |= xc_domain_memory_mapping(xc_handle, dom, + 0xa0000 >> XC_PAGE_SHIFT, + 0xa0000 >> XC_PAGE_SHIFT, + 2 * 16, 1); + rc |= linux_map_vga_ioport(xc_handle, dom); + + 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 +279,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 ) @@ -190,7 +303,7 @@ static int setup_guest(int xc_handle, goto error_out; } - IPRINTF("VIRTUAL MEMORY ARRANGEMENT:\n" + fprintf(stderr, "VIRTUAL MEMORY ARRANGEMENT:\n" " Loader: %016"PRIx64"->%016"PRIx64"\n" " TOTAL: %016"PRIx64"->%016"PRIx64"\n" " ENTRY ADDRESS: %016"PRIx64"\n", @@ -314,6 +427,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 +446,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 +455,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,9 +470,10 @@ 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; + char *image; int sts; unsigned long image_size; @@ -358,7 +481,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 +496,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 +519,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 11:53:08 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 11:53:08 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 11:53:08 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 11:53:08 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 11:53:08 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 11:53:08 2008 +0100 @@ -310,6 +310,10 @@ class ImageHandler: if int(vmConfig['platform'].get('monitor', 0)) != 0: ret = ret + ['-monitor', 'vc'] + + if (int(vmConfig['platform'].get('vga_passthrough', 0))) == 1: + ret.append('-enable-dom0'); + return ret def getDeviceModelArgs(self, restore = False): @@ -536,6 +540,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 +666,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 +674,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 11:53:08 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 11:53:08 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 11:53:08 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 11:53:08 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 |