[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] Getting VGA Passthrough to work on Xen Unstable
Hi all, I've tried to filter out parts of XCI that are relevant to VGA passthrough (most, if not all, are Jean Guyader's work) and apply them to Xen unstable. The patch doesn't work with changeset 19597. I'm not sure why. But I've gotten DomU to boot up showing only the physical gfx on previous changesets. I didn't have a chance to test the gfx functionalities though. I made a lot of simplifications, such as excluding user options, and ignoring HID passthrough for now. The patch is hardcoded for VGA passthrough on HVM guests. The reason is really to study which are the parts really affect VGA passthrough, and of course ultimately getting VGA passthrough to work. This may seem like taking a step backwards, but I think there are many people out there who are new, like me, and are really interested to understand and get VGA passthrough to work correctly. I'm hoping that experts out there can provide constructive criticism on this patch, and of course provide suggestions on how to make this patch work for the latest changeset. - Beng Heng diff -rupN -X diffignore --ignore-all-space a/tools/firmware/hvmloader/hvmloader.c b/tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c 2009-05-11 14:19:39.000000000 -0400 +++ b/tools/firmware/hvmloader/hvmloader.c 2009-05-13 11:42:26.000000000 -0400 @@ -187,7 +187,9 @@ static void pci_setup(void) class = pci_readw(devfn, PCI_CLASS_DEVICE); vendor_id = pci_readw(devfn, PCI_VENDOR_ID); device_id = pci_readw(devfn, PCI_DEVICE_ID); - if ( (vendor_id == 0xffff) && (device_id == 0xffff) ) + if ( ((vendor_id == 0xffff) && (device_id == 0xffff)) || + ((vendor_id == 0x1234) && (device_id == 0x1111)) || + ((vendor_id == 0x1013) && (device_id == 0xb8)) ) continue; ASSERT((devfn != PCI_ISA_DEVFN) || diff -rupN -X diffignore --ignore-all-space a/tools/ioemu-remote/hw/pc.c b/tools/ioemu-remote/hw/pc.c --- a/tools/ioemu-remote/hw/pc.c 2009-05-13 08:16:54.000000000 -0400 +++ b/tools/ioemu-remote/hw/pc.c 2009-05-14 05:35:11.000000000 -0400 @@ -805,6 +805,7 @@ static void pc_init1(ram_addr_t ram_size BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BlockDriverState *fd[MAX_FD]; int rc; + unsigned long vga_pt_enabled = 1; if (ram_size >= 0xe0000000 ) { above_4g_mem_size = ram_size - 0xe0000000; @@ -890,8 +891,10 @@ static void pc_init1(ram_addr_t ram_size exit(1); } - if (cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled) { + if ((cirrus_vga_enabled || std_vga_enabled || vmsvga_enabled) && !vga_pt_enabled) { /* VGA BIOS load */ if (cirrus_vga_enabled) { snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_CIRRUS_FILENAME); @@ -984,6 +988,8 @@ vga_bios_error: register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL); + if (!vga_pt_enabled) + { if (cirrus_vga_enabled) { if (pci_enabled) { pci_cirrus_vga_init(pci_bus, @@ -1010,6 +1016,7 @@ vga_bios_error: vga_ram_addr, vga_ram_size); } } + } #ifdef CONFIG_PASSTHROUGH /* Pass-through Initialization diff -rupN -X diffignore --ignore-all-space a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c 2009-05-11 14:19:40.000000000 -0400 +++ b/xen/arch/x86/hvm/hvm.c 2009-05-14 13:25:46.000000000 -0400 @@ -297,6 +297,7 @@ static int hvm_print_line( int hvm_domain_initialise(struct domain *d) { int rc; + unsigned long vga_pt_enabled = 1; if ( !hvm_enabled ) { @@ -328,6 +329,7 @@ int hvm_domain_initialise(struct domain if ( rc != 0 ) goto fail1; + if(!vga_pt_enabled) stdvga_init(d); rtc_init(d); @@ -345,6 +347,7 @@ int hvm_domain_initialise(struct domain fail2: rtc_deinit(d); + if(!vga_pt_enabled) stdvga_deinit(d); vioapic_deinit(d); fail1: diff -rupN -X diffignore --ignore-all-space a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h 2009-05-11 14:19:39.000000000 -0400 +++ b/tools/libxc/xenctrl.h 2009-05-12 14:02:46.000000000 -0400 @@ -145,6 +145,10 @@ int xc_waitdomain( int *status, int options); +int xc_get_vgabios( + unsigned char *bios, + int len); + #endif /* __linux__ */ /* diff -rupN -X diffignore --ignore-all-space a/tools/libxc/xc_linux.c b/tools/libxc/xc_linux.c --- a/tools/libxc/xc_linux.c 2009-05-11 14:19:39.000000000 -0400 +++ b/tools/libxc/xc_linux.c 2009-05-12 14:01:56.000000000 -0400 @@ -562,6 +562,57 @@ 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, size = 0; + uint16_t magic = 0; + + start = 0xC0000; + if (len < size) + return 0; + if ((mem = open("/dev/mem", O_RDONLY)) < 0) + return 0; + + /* + ** Check if it a real bios extension. + ** The magic number is 0xAA55. + */ + if (start != lseek(mem, start, SEEK_SET)) + goto out; + if (read(mem, &magic, 2) != 2) + goto out; + if (magic != 0xAA55) + goto out; + + /* Find the size of the rom extension */ + if (start != lseek(mem, start, SEEK_SET)) + goto out; + if (lseek(mem, 2, SEEK_CUR) != (start + 2)) + goto out; + if (read(mem, &size, 1) != 1) + goto out; + /* This size is in 512K */ + size *= 512; + + /* + ** Set the file to the begining of the rombios, + ** to start the copy. + */ + if (start != lseek(mem, start, SEEK_SET)) + { + size = 0; + goto out; + } + if (size != read(mem, buf, size)) + size = 0; + +out: + close(mem); + return size; +} + diff -rupN -X diffignore --ignore-all-space a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c --- a/tools/libxc/xc_hvm_build.c 2009-05-11 14:19:39.000000000 -0400 +++ b/tools/libxc/xc_hvm_build.c 2009-05-14 12:38:56.000000000 -0400 @@ -66,6 +66,66 @@ static void build_hvm_info(void *hvm_inf hvm_info->checksum = -sum; } +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; + char *c = NULL; + char checksum = 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; + } + + /* Adjust the bios checksum */ + for ( c = (char*)bios; c < ((char*)bios + bios_size); c++ ) + checksum += *c; + if (checksum) + bios[bios_size - 1] -= checksum; + + memcpy(va_bios, bios, bios_size); + munmap(va_bios, va_size); +error: + free(bios); + + return rc; +} + static int loadelfimage( struct elf_binary *elf, int xch, uint32_t dom, unsigned long *parray) { @@ -359,12 +419,17 @@ int xc_hvm_build(int xc_handle, char *image; int sts; unsigned long image_size; + unsigned long vga_pt_enabled = 1; if ( (image_name == NULL) || ((image = xc_read_image(image_name, &image_size)) == NULL) ) return -1; sts = xc_hvm_build_internal(xc_handle, domid, memsize, memsize, image, image_size); + if ( vga_pt_enabled ) { + sts |= setup_vga_pt(xc_handle, domid); + } free(image); _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |