aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Cooper <andrew.cooper3@citrix.com>2013-07-16 11:10:45 +0200
committerJan Beulich <jbeulich@suse.com>2013-07-16 11:10:45 +0200
commitfca11da0ec956b17d7450d7776c3ffa22a8f538a (patch)
tree6c8fb36877d4f67043e4812ea16d3c134a27623d
parentd7f913b8de206464f2a18e4c6d20886d32483de3 (diff)
downloadxen-fca11da0ec956b17d7450d7776c3ffa22a8f538a.tar.gz
xen-fca11da0ec956b17d7450d7776c3ffa22a8f538a.tar.bz2
xen-fca11da0ec956b17d7450d7776c3ffa22a8f538a.zip
x86: Special case __HYPERVISOR_iret rather more when writing hypercall pages
In all cases when a hypercall page is written, __HYPERVISOR_iret is first written as a regular hypercall, then subsequently rewritten in its special case. For VMX and SVM, this means that following the ud2a instruction is 3 bytes of an imm32 parameter. For a ring3 kernel, this means that following the syscall instruction is the second half of 'pop %r11'. For a ring1 kernel, the iret case ends up as the same number of bytes as the rest of the hypercalls, but it is pointless writing it twice, and is changed for consistency. Therefore, skip the loop iteration which would write the incorrect __HYPERVISOR_iret hypercall. This removes junk machine code from the tail and makes disassemblers rather more happy when looking at the hypercall page. Also, a miscellaneous whitespace fix in the comment for ring3 kernel. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
-rw-r--r--xen/arch/x86/hvm/svm/svm.c3
-rw-r--r--xen/arch/x86/hvm/vmx/vmx.c3
-rw-r--r--xen/arch/x86/x86_64/compat/traps.c3
-rw-r--r--xen/arch/x86/x86_64/traps.c7
4 files changed, 14 insertions, 2 deletions
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 4a7aeeecf5..4cc4b15315 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -759,6 +759,9 @@ static void svm_init_hypercall_page(struct domain *d, void *hypercall_page)
for ( i = 0; i < (PAGE_SIZE / 32); i++ )
{
+ if ( i == __HYPERVISOR_iret )
+ continue;
+
p = (char *)(hypercall_page + (i * 32));
*(u8 *)(p + 0) = 0xb8; /* mov imm32, %eax */
*(u32 *)(p + 1) = i;
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index 059d258d2d..d6540e3d79 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -950,6 +950,9 @@ static void vmx_init_hypercall_page(struct domain *d, void *hypercall_page)
for ( i = 0; i < (PAGE_SIZE / 32); i++ )
{
+ if ( i == __HYPERVISOR_iret )
+ continue;
+
p = (char *)(hypercall_page + (i * 32));
*(u8 *)(p + 0) = 0xb8; /* mov imm32, %eax */
*(u32 *)(p + 1) = i;
diff --git a/xen/arch/x86/x86_64/compat/traps.c b/xen/arch/x86/x86_64/compat/traps.c
index 6816b0ed6a..21a82b91eb 100644
--- a/xen/arch/x86/x86_64/compat/traps.c
+++ b/xen/arch/x86/x86_64/compat/traps.c
@@ -367,6 +367,9 @@ static void hypercall_page_initialise_ring1_kernel(void *hypercall_page)
for ( i = 0; i < (PAGE_SIZE / 32); i++ )
{
+ if ( i == __HYPERVISOR_iret )
+ continue;
+
p = (char *)(hypercall_page + (i * 32));
*(u8 *)(p+ 0) = 0xb8; /* mov $<i>,%eax */
*(u32 *)(p+ 1) = i;
diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
index eec919aebb..bcd760908e 100644
--- a/xen/arch/x86/x86_64/traps.c
+++ b/xen/arch/x86/x86_64/traps.c
@@ -590,6 +590,9 @@ static void hypercall_page_initialise_ring3_kernel(void *hypercall_page)
/* Fill in all the transfer points with template machine code. */
for ( i = 0; i < (PAGE_SIZE / 32); i++ )
{
+ if ( i == __HYPERVISOR_iret )
+ continue;
+
p = (char *)(hypercall_page + (i * 32));
*(u8 *)(p+ 0) = 0x51; /* push %rcx */
*(u16 *)(p+ 1) = 0x5341; /* push %r11 */
@@ -602,8 +605,8 @@ static void hypercall_page_initialise_ring3_kernel(void *hypercall_page)
}
/*
- * HYPERVISOR_iret is special because it doesn't return and expects a
- * special stack frame. Guests jump at this transfer point instead of
+ * HYPERVISOR_iret is special because it doesn't return and expects a
+ * special stack frame. Guests jump at this transfer point instead of
* calling it.
*/
p = (char *)(hypercall_page + (__HYPERVISOR_iret * 32));