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
|