[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.