[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

 


Rackspace

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