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@eu.citrix.com> --- 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 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Sorry, I forgot a file in my previous patch. -- Jean Guyader _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jean Guyader, le Fri 09 May 2008 12:11:44 +0100, a écrit :> - Then we start qemu with the new option -enable-dom0 to have the > dom0''s keyboard and the mouse redirected into the guest.I would suggest to a more expressive name, like -dom0-input> Be careful, vnc must be at 0.Can''t you have the dom0 option override the vnc option?> + if (!(mem = fopen("/dev/mem", "r"))) > + return 0; > + > + fseek(mem, start, SEEK_SET); > + fread(buf, 1, size, mem); > + fclose(mem);Mmm, no need for f functionnalities, you can just replace it with open/lseek/read/close.> + 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,use bios_size here instead?> + 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);use (0xc0000 - 0xa0000) >> XC_PAGE_SHIFT instead?> @@ -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"Mmm, I guess you should not change that :) Samuel _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Samuel Thibault
2008-May-09 11:32 UTC
Re: [Xen-devel] Re: [PATCH] Pass-through a graphic card
Jean Guyader, le Fri 09 May 2008 12:18:15 +0100, a écrit :> +#define EVENT_MAX 10 > +#define EVENT_PATH "/dev/input/event" > + > +struct dom0_driver > +{ > + int event_fds[EVENT_MAX]; > + int mouse_button_state; > +};Dynamically allocate event_fds instead of having a fixed limit? (I have already 8 input devices on my laptop ;) ) Samuel _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Here, a new patch with the modifications that Samuel suggested. -- Jean Guyader _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Daniel P. Berrange
2008-May-09 14:02 UTC
Re: [Xen-devel] [PATCH] Pass-through a graphic card
On Fri, May 09, 2008 at 02:56:47PM +0100, Jean Guyader wrote:> > Here, a new patch with the modifications that Samuel suggested.Could you adjust your mail client so it attaches patches as text/plain or include them inline to the body. Using text/xdiff means that many mail clients won''t quote the patch when replying making sending patch feedback really much more difficult / convoluted Regards, Daniel. -- |: Red Hat, Engineering, Boston -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Daniel P. Berrange
2008-May-09 14:25 UTC
Re: [Xen-devel] [PATCH] Pass-through a graphic card
On Fri, May 09, 2008 at 02:56:47PM +0100, Jean Guyader wrote:> > Here, a new patch with the modifications that Samuel suggested.> +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 (struct input_event) * 5);Could simply do ''sizeof(event)'' here I believe.> +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); > + > + driver.event_fds = realloc(driver.event_fds, > + driver.event_nb + 1);Error checking on reallocs...> + ioctl(fd, EVIOCGRAB, 1);ioctls can fail.> + 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); > +}> 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 14:53:11 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 */This API can return a failure code.> @@ -152,9 +152,122 @@ 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))Should be also checking 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; > + > + lseek(mem, start, SEEK_SET); > + read(mem, buf, size);Check for failure / partial reads.> +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))Also check 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) > + { > + free(bios); > + return -1; > + } > + > + va_bios = xc_map_foreign_range(xc_handle, dom, > + bios_size + bios_size % XC_PAGE_SIZE, > + PROT_READ | PROT_WRITE, pfn);This call can fail.> @@ -348,9 +471,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;Needless whitespace error. Regards, Daniel -- |: Red Hat, Engineering, Boston -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Thanks for the feedbacks. Here a new version of this patch with more error handling. -- Jean Guyader _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Hi, Here a new version of the vga pass through patch. The HVM_PARAM was removed, in that way this patch doesn''t change anything in the hypervisor. This patch has to be applied instead the previous one. Thanks to all people who have tried this experimental patch by them self. Please continue to send my your feedback. --- 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. - Then we start qemu with the new option -enable-dom0 to have the dom0''s keyboard and the mouse redirected into the guest. Signed-off-by: Jean Guyader <jean.guyader@eu.citrix.com> -- Jean Guyader _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Jean Guyader, le Thu 15 May 2008 11:11:10 +0100, a écrit :> > +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); > +} > +Mmm, maybe enabled and bios_size are redundant, since bios_size > 0 implies enabled? Samuel _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Samuel Thibault wrote:> Jean Guyader, le Thu 15 May 2008 11:11:10 +0100, a écrit : >> >> +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); >> +} >> + > > Mmm, maybe enabled and bios_size are redundant, since bios_size > 0 > implies enabled? >Yes, but it doesn''t really matter. I am rewriting the patch to not use this thing any more. -- Jean Guyader _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
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@eu.citrix.com> -- Jean Guyader _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Hello, Jean Guyader, le Fri 16 May 2008 09:59:17 +0100, a écrit :> - Copy directly the VGABIOS at the right place (0xC0000) into the > guest memory.Mmm, then can''t we just map the physical 0xC0000-0xCxyzt pages? Samuel _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel