aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-12-09 16:28:02 +0000
committerKeir Fraser <keir.fraser@citrix.com>2008-12-09 16:28:02 +0000
commit8d4638d15e10d2d52547195dd6b57402b5382cce (patch)
tree768819983f8a3eebd83b897bf28835ea0540f84b /tools
parentdbc75f4a5b8300ed2ef4bd2005b986953ddaf9b3 (diff)
downloadxen-8d4638d15e10d2d52547195dd6b57402b5382cce.tar.gz
xen-8d4638d15e10d2d52547195dd6b57402b5382cce.tar.bz2
xen-8d4638d15e10d2d52547195dd6b57402b5382cce.zip
Use virtual 8086 mode for VMX guests with CR0.PE == 0
When a VMX guest tries to enter real mode, put it in virtual 8086 mode instead, if that's possible. Handle all errors and corner cases by falling back to the real-mode emulator. This is similar to the old VMXASSIST system except it uses Xen's x86_emulate emulator instead of having a partial emulator in the guest firmware. It more than doubles the speed of real-mode operation on VMX. Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/firmware/hvmloader/hvmloader.c19
-rw-r--r--tools/libxc/xc_domain_restore.c16
-rw-r--r--tools/libxc/xc_domain_save.c22
3 files changed, 52 insertions, 5 deletions
diff --git a/tools/firmware/hvmloader/hvmloader.c b/tools/firmware/hvmloader/hvmloader.c
index ec066cbf68..bff548f9f2 100644
--- a/tools/firmware/hvmloader/hvmloader.c
+++ b/tools/firmware/hvmloader/hvmloader.c
@@ -536,6 +536,23 @@ static uint16_t init_xen_platform_io_base(void)
return bios_info->xen_pfiob;
}
+/* Set up an empty TSS area for virtual 8086 mode to use.
+ * The only important thing is that it musn't have any bits set
+ * in the interrupt redirection bitmap, so all zeros will do. */
+static void init_vm86_tss(void)
+{
+ uint32_t tss;
+ struct xen_hvm_param p;
+
+ tss = e820_malloc(128, 128);
+ memset((char *)tss, 0, 128);
+ p.domid = DOMID_SELF;
+ p.index = HVM_PARAM_VM86_TSS;
+ p.value = tss;
+ hypercall_hvm_op(HVMOP_set_param, &p);
+ printf("vm86 TSS at %08x\n", tss);
+}
+
int main(void)
{
int option_rom_sz = 0, vgabios_sz = 0, etherboot_sz = 0;
@@ -606,6 +623,8 @@ int main(void)
acpi_build_tables();
}
+ init_vm86_tss();
+
cmos_write_memory_size();
printf("BIOS map:\n");
diff --git a/tools/libxc/xc_domain_restore.c b/tools/libxc/xc_domain_restore.c
index 1916728495..4f92ebb549 100644
--- a/tools/libxc/xc_domain_restore.c
+++ b/tools/libxc/xc_domain_restore.c
@@ -490,6 +490,22 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
continue;
}
+ if ( j == -4 )
+ {
+ uint64_t vm86_tss;
+
+ /* Skip padding 4 bytes then read the vm86 TSS location. */
+ if ( read_exact(io_fd, &vm86_tss, sizeof(uint32_t)) ||
+ read_exact(io_fd, &vm86_tss, sizeof(uint64_t)) )
+ {
+ ERROR("error read the address of the vm86 TSS");
+ goto out;
+ }
+
+ xc_set_hvm_param(xc_handle, dom, HVM_PARAM_VM86_TSS, vm86_tss);
+ continue;
+ }
+
if ( j == 0 )
break; /* our work here is done */
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index a910414988..efd581966c 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -1388,20 +1388,32 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
if ( hvm )
{
struct {
- int minusthree;
+ int id;
uint32_t pad;
- uint64_t ident_pt;
- } chunk = { -3, 0 };
+ uint64_t data;
+ } chunk = { 0, };
+ chunk.id = -3;
xc_get_hvm_param(xc_handle, dom, HVM_PARAM_IDENT_PT,
- (unsigned long *)&chunk.ident_pt);
+ (unsigned long *)&chunk.data);
- if ( (chunk.ident_pt != 0) &&
+ if ( (chunk.data != 0) &&
write_exact(io_fd, &chunk, sizeof(chunk)) )
{
PERROR("Error when writing the ident_pt for EPT guest");
goto out;
}
+
+ chunk.id = -4;
+ xc_get_hvm_param(xc_handle, dom, HVM_PARAM_VM86_TSS,
+ (unsigned long *)&chunk.data);
+
+ if ( (chunk.data != 0) &&
+ write_exact(io_fd, &chunk, sizeof(chunk)) )
+ {
+ PERROR("Error when writing the vm86 TSS for guest");
+ goto out;
+ }
}
/* Zero terminate */