From: Jean Guyader <jean.guyader@eu.citrix.com>
To: xen-devel@lists.xensource.com
Cc: Ian Pratt <Ian.Pratt@eu.citrix.com>,
Keir Fraser <keir.fraser@eu.citrix.com>,
Kamala Narasimhan <Kamala.Narasimhan@citrix.com>
Subject: [PATCH] Pass-through a graphic card
Date: Fri, 09 May 2008 12:11:44 +0100 [thread overview]
Message-ID: <48243170.7050706@eu.citrix.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1254 bytes --]
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
[-- Attachment #2: vga_pt.patch --]
[-- Type: text/x-diff, Size: 24964 bytes --]
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__ */
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
next reply other threads:[~2008-05-09 11:11 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-09 11:11 Jean Guyader [this message]
2008-05-09 11:18 ` [PATCH] Pass-through a graphic card Jean Guyader
2008-05-09 11:32 ` Samuel Thibault
2008-05-09 11:27 ` Samuel Thibault
2008-05-09 13:56 ` Jean Guyader
2008-05-09 14:02 ` Daniel P. Berrange
2008-05-09 14:25 ` Daniel P. Berrange
2008-05-09 15:47 ` Jean Guyader
2008-05-15 10:11 ` Jean Guyader
2008-05-15 11:13 ` Samuel Thibault
2008-05-15 11:17 ` Jean Guyader
2008-05-16 8:59 ` Jean Guyader
2008-05-16 17:15 ` Samuel Thibault
-- strict thread matches above, loose matches on Subject: below --
2008-06-13 15:08 mail mark
2008-06-13 15:25 ` Jean Guyader
2008-06-21 17:36 ` mail mark
2008-06-21 19:28 ` Jean Guyader
2008-06-23 13:20 ` mail mark
2008-06-21 17:43 ` Neo Jia
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=48243170.7050706@eu.citrix.com \
--to=jean.guyader@eu.citrix.com \
--cc=Ian.Pratt@eu.citrix.com \
--cc=Kamala.Narasimhan@citrix.com \
--cc=keir.fraser@eu.citrix.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.