[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] Indirect hypercalls through a hypercall transfer page.



# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 71914b64b5770285cf095c1906e346b814f4878b
# Parent  246b6444c6432193ea98c9f01de58e6740bde09c
Indirect hypercalls through a hypercall transfer page.

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 246b6444c643 -r 71914b64b577 
linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Tue Jan 24 16:59:54 2006
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Tue Jan 24 17:05:45 2006
@@ -333,10 +333,8 @@
 hypervisor_iret:
        andl $~NMI_MASK, EFLAGS(%esp)
        RESTORE_REGS
-       movl %eax,(%esp)
-       movl $__HYPERVISOR_iret,%eax
-       int $0x82
-       ud2
+       addl $4, %esp
+       jmp  hypercall_page + (__HYPERVISOR_iret * 32)
 
 #if 0 /* XEN */
 ldt_ss:
diff -r 246b6444c643 -r 71914b64b577 
linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S
--- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S  Tue Jan 24 16:59:54 2006
+++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S  Tue Jan 24 17:05:45 2006
@@ -5,6 +5,7 @@
        .ascii  "GUEST_OS=linux,GUEST_VER=2.6"
        .ascii  ",XEN_VER=xen-3.0"
        .ascii  ",VIRT_BASE=0xC0000000"
+       .ascii  ",HYPERCALL_PAGE=0x104" /* __pa(hypercall_page) >> 12 */
 #ifdef CONFIG_X86_PAE
        .ascii  ",PAE=yes"
 #else
@@ -187,6 +188,9 @@
 ENTRY(default_ldt)
 
 .org 0x4000
+ENTRY(hypercall_page)
+
+.org 0x5000
 /*
  * Real beginning of normal "text" segment
  */
diff -r 246b6444c643 -r 71914b64b577 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S       Tue Jan 24 
16:59:54 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S       Tue Jan 24 
17:05:45 2006
@@ -127,15 +127,10 @@
          *     };
          * #define VGCF_IN_SYSCALL (1<<8) 
          */
-        .macro HYPERVISOR_IRET flag
-        subq $8*4,%rsp                   # reuse rip, cs, rflags, rsp, ss in 
the stack
-        movq %rax,(%rsp)
-        movq %r11,1*8(%rsp)
-        movq %rcx,2*8(%rsp)              # we saved %rcx upon exceptions
-        movq $\flag,3*8(%rsp)
-        movq $__HYPERVISOR_iret,%rax
-        syscall
-        .endm
+       .macro HYPERVISOR_IRET flag
+       pushq $\flag
+       jmp  hypercall_page + (__HYPERVISOR_iret * 32)
+       .endm
 
         .macro SWITCH_TO_KERNEL ssoff,adjust=0
        jc  1f
diff -r 246b6444c643 -r 71914b64b577 
linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S
--- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S        Tue Jan 24 
16:59:54 2006
+++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S        Tue Jan 24 
17:05:45 2006
@@ -16,9 +16,11 @@
 #include <linux/linkage.h>
 
 .section __xen_guest
-       .ascii  
"GUEST_OS=linux,GUEST_VER=2.6,XEN_VER=xen-3.0,VIRT_BASE=0xffffffff80000000"
+       .ascii  "GUEST_OS=linux,GUEST_VER=2.6"
+       .ascii  ",XEN_VER=xen-3.0"
+       .ascii  ",VIRT_BASE=0xffffffff80000000"
+       .ascii  ",HYPERCALL_PAGE=0x10d" /* __pa(hypercall_page) >> 12 */
        .ascii  ",LOADER=generic"
-/*     .ascii  ",PT_MODE_WRITABLE" */
        .byte   0
                 
       
@@ -227,8 +229,10 @@
 ENTRY(level3_physmem_pgt)
        .quad   0x0000000000105007              /* -> level2_kernel_pgt (so 
that __va works even before pagetable_init) */
 
-       
-       .org 0xd000
+.org 0xd000
+ENTRY(hypercall_page)
+
+.org 0xe000
 #ifdef CONFIG_ACPI_SLEEP
 ENTRY(wakeup_level4_pgt)
        .quad   0x0000000000102007              /* -> level3_ident_pgt */
diff -r 246b6444c643 -r 71914b64b577 
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Tue Jan 24 
16:59:54 2006
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c        Tue Jan 24 
17:05:45 2006
@@ -58,7 +58,9 @@
                        "movl 16(%%eax),%%esi ;"
                        "movl 20(%%eax),%%edi ;"
                        "movl   (%%eax),%%eax ;"
-                       TRAP_INSTR "; "
+                       "shll $5,%%eax ;"
+                       "addl $hypercall_page,%%eax ;"
+                       "call *%%eax ;"
                        "popl %%edi; popl %%esi; popl %%edx; "
                        "popl %%ecx; popl %%ebx"
                        : "=a" (ret) : "0" (&hypercall) : "memory" );
@@ -66,7 +68,10 @@
                {
                        long ign1, ign2, ign3;
                        __asm__ __volatile__ (
-                               "movq %8,%%r10; movq %9,%%r8;" TRAP_INSTR
+                               "movq %8,%%r10; movq %9,%%r8;"
+                               "shlq $5,%%rax ;"
+                               "addq $hypercall_page,%%rax ;"
+                               "call *%%rax"
                                : "=a" (ret), "=D" (ign1),
                                  "=S" (ign2), "=d" (ign3)
                                : "0" ((unsigned long)hypercall.op), 
@@ -75,7 +80,7 @@
                                "3" ((unsigned long)hypercall.arg[2]), 
                                "g" ((unsigned long)hypercall.arg[3]),
                                "g" ((unsigned long)hypercall.arg[4])
-                               : "r11","rcx","r8","r10","memory");
+                               : "r8", "r10", "memory" );
                }
 #elif defined (__ia64__)
                __asm__ __volatile__ (
diff -r 246b6444c643 -r 71914b64b577 
linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Tue Jan 24 
16:59:54 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Tue Jan 24 
17:05:45 2006
@@ -34,13 +34,15 @@
 #include <asm-xen/xen-public/sched.h>
 #include <asm-xen/xen-public/nmi.h>
 
+#define __STR(x) #x
+#define STR(x) __STR(x)
+
 #define _hypercall0(type, name)                        \
 ({                                             \
        long __res;                             \
        asm volatile (                          \
-               TRAP_INSTR                      \
+               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
                : "=a" (__res)                  \
-               : "0" (__HYPERVISOR_##name)     \
                : "memory" );                   \
        (type)__res;                            \
 })
@@ -49,9 +51,9 @@
 ({                                                             \
        long __res, __ign1;                                     \
        asm volatile (                                          \
-               TRAP_INSTR                                      \
+               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
                : "=a" (__res), "=b" (__ign1)                   \
-               : "0" (__HYPERVISOR_##name), "1" ((long)(a1))   \
+               : "1" ((long)(a1))                              \
                : "memory" );                                   \
        (type)__res;                                            \
 })
@@ -60,10 +62,9 @@
 ({                                                             \
        long __res, __ign1, __ign2;                             \
        asm volatile (                                          \
-               TRAP_INSTR                                      \
+               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
                : "=a" (__res), "=b" (__ign1), "=c" (__ign2)    \
-               : "0" (__HYPERVISOR_##name), "1" ((long)(a1)),  \
-               "2" ((long)(a2))                                \
+               : "1" ((long)(a1)), "2" ((long)(a2))            \
                : "memory" );                                   \
        (type)__res;                                            \
 })
@@ -72,11 +73,11 @@
 ({                                                             \
        long __res, __ign1, __ign2, __ign3;                     \
        asm volatile (                                          \
-               TRAP_INSTR                                      \
+               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
                : "=a" (__res), "=b" (__ign1), "=c" (__ign2),   \
                "=d" (__ign3)                                   \
-               : "0" (__HYPERVISOR_##name), "1" ((long)(a1)),  \
-               "2" ((long)(a2)), "3" ((long)(a3))              \
+               : "1" ((long)(a1)), "2" ((long)(a2)),           \
+               "3" ((long)(a3))                                \
                : "memory" );                                   \
        (type)__res;                                            \
 })
@@ -85,12 +86,11 @@
 ({                                                             \
        long __res, __ign1, __ign2, __ign3, __ign4;             \
        asm volatile (                                          \
-               TRAP_INSTR                                      \
+               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
                : "=a" (__res), "=b" (__ign1), "=c" (__ign2),   \
                "=d" (__ign3), "=S" (__ign4)                    \
-               : "0" (__HYPERVISOR_##name), "1" ((long)(a1)),  \
-               "2" ((long)(a2)), "3" ((long)(a3)),             \
-               "4" ((long)(a4))                                \
+               : "1" ((long)(a1)), "2" ((long)(a2)),           \
+               "3" ((long)(a3)), "4" ((long)(a4))              \
                : "memory" );                                   \
        (type)__res;                                            \
 })
@@ -99,12 +99,12 @@
 ({                                                             \
        long __res, __ign1, __ign2, __ign3, __ign4, __ign5;     \
        asm volatile (                                          \
-               TRAP_INSTR                                      \
+               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
                : "=a" (__res), "=b" (__ign1), "=c" (__ign2),   \
                "=d" (__ign3), "=S" (__ign4), "=D" (__ign5)     \
-               : "0" (__HYPERVISOR_##name), "1" ((long)(a1)),  \
-               "2" ((long)(a2)), "3" ((long)(a3)),             \
-               "4" ((long)(a4)), "5" ((long)(a5))              \
+               : "1" ((long)(a1)), "2" ((long)(a2)),           \
+               "3" ((long)(a3)), "4" ((long)(a4)),             \
+               "5" ((long)(a5))                                \
                : "memory" );                                   \
        (type)__res;                                            \
 })
diff -r 246b6444c643 -r 71914b64b577 
linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h       Tue Jan 
24 16:59:54 2006
+++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h       Tue Jan 
24 17:05:45 2006
@@ -37,16 +37,16 @@
 #include <asm-xen/xen-public/xen.h>
 #include <asm-xen/xen-public/sched.h>
 
-#define __syscall_clobber "r11","rcx","memory"
+#define __STR(x) #x
+#define STR(x) __STR(x)
 
 #define _hypercall0(type, name)                        \
 ({                                             \
        long __res;                             \
        asm volatile (                          \
-               TRAP_INSTR                      \
+               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
                : "=a" (__res)                  \
-               : "0" (__HYPERVISOR_##name)     \
-               : __syscall_clobber );          \
+               : "memory" );                   \
        (type)__res;                            \
 })
 
@@ -54,10 +54,10 @@
 ({                                                             \
        long __res, __ign1;                                     \
        asm volatile (                                          \
-               TRAP_INSTR                                      \
+               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
                : "=a" (__res), "=D" (__ign1)                   \
-               : "0" (__HYPERVISOR_##name), "1" ((long)(a1))   \
-               : __syscall_clobber );                          \
+               : "1" ((long)(a1))                              \
+               : "memory" );                                   \
        (type)__res;                                            \
 })
 
@@ -65,11 +65,10 @@
 ({                                                             \
        long __res, __ign1, __ign2;                             \
        asm volatile (                                          \
-               TRAP_INSTR                                      \
+               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
                : "=a" (__res), "=D" (__ign1), "=S" (__ign2)    \
-               : "0" (__HYPERVISOR_##name), "1" ((long)(a1)),  \
-               "2" ((long)(a2))                                \
-               : __syscall_clobber );                          \
+               : "1" ((long)(a1)), "2" ((long)(a2))            \
+               : "memory" );                                   \
        (type)__res;                                            \
 })
 
@@ -77,12 +76,12 @@
 ({                                                             \
        long __res, __ign1, __ign2, __ign3;                     \
        asm volatile (                                          \
-               TRAP_INSTR                                      \
+               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
                : "=a" (__res), "=D" (__ign1), "=S" (__ign2),   \
                "=d" (__ign3)                                   \
-               : "0" (__HYPERVISOR_##name), "1" ((long)(a1)),  \
-               "2" ((long)(a2)), "3" ((long)(a3))              \
-               : __syscall_clobber );                          \
+               : "1" ((long)(a1)), "2" ((long)(a2)),           \
+               "3" ((long)(a3))                                \
+               : "memory" );                                   \
        (type)__res;                                            \
 })
 
@@ -90,13 +89,13 @@
 ({                                                             \
        long __res, __ign1, __ign2, __ign3;                     \
        asm volatile (                                          \
-               "movq %8,%%r10; " TRAP_INSTR                    \
+               "movq %8,%%r10; "                               \
+               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
                : "=a" (__res), "=D" (__ign1), "=S" (__ign2),   \
                "=d" (__ign3)                                   \
-               : "0" (__HYPERVISOR_##name), "1" ((long)(a1)),  \
-               "2" ((long)(a2)), "3" ((long)(a3)),             \
-               "g" ((long)(a4))                                \
-               : __syscall_clobber, "r10" );                   \
+               : "1" ((long)(a1)), "2" ((long)(a2)),           \
+               "3" ((long)(a3)), "g" ((long)(a4))              \
+               : "memory", "r10" );                            \
        (type)__res;                                            \
 })
 
@@ -104,13 +103,14 @@
 ({                                                             \
        long __res, __ign1, __ign2, __ign3;                     \
        asm volatile (                                          \
-               "movq %8,%%r10; movq %9,%%r8; " TRAP_INSTR      \
+               "movq %8,%%r10; movq %9,%%r8; "                 \
+               "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
                : "=a" (__res), "=D" (__ign1), "=S" (__ign2),   \
                "=d" (__ign3)                                   \
-               : "0" (__HYPERVISOR_##name), "1" ((long)(a1)),  \
-               "2" ((long)(a2)), "3" ((long)(a3)),             \
-               "g" ((long)(a4)), "g" ((long)(a5))              \
-               : __syscall_clobber, "r10", "r8" );             \
+               : "1" ((long)(a1)), "2" ((long)(a2)),           \
+               "3" ((long)(a3)), "g" ((long)(a4)),             \
+               "g" ((long)(a5))                                \
+               : "memory", "r10", "r8" );                      \
        (type)__res;                                            \
 })
 
diff -r 246b6444c643 -r 71914b64b577 tools/libxc/xc_linux_build.c
--- a/tools/libxc/xc_linux_build.c      Tue Jan 24 16:59:54 2006
+++ b/tools/libxc/xc_linux_build.c      Tue Jan 24 17:05:45 2006
@@ -429,10 +429,12 @@
                        unsigned int console_evtchn, unsigned long *console_mfn)
 {
     unsigned long *page_array = NULL;
-    unsigned long count, i;
+    unsigned long count, i, hypercall_pfn;
     start_info_t *start_info;
     shared_info_t *shared_info;
     xc_mmu_t *mmu = NULL;
+    char *p;
+    DECLARE_DOM0_OP;
     int rc;
 
     unsigned long nr_pt_pages;
@@ -714,6 +716,20 @@
     /* Send the page update requests down to the hypervisor. */
     if ( xc_finish_mmu_updates(xc_handle, mmu) )
         goto error_out;
+
+    p = strstr(dsi.xen_guest_string, "HYPERCALL_PAGE=");
+    if ( p != NULL )
+    {
+        p += strlen("HYPERCALL_PAGE=");
+        hypercall_pfn = strtoul(p, NULL, 16);
+        if ( hypercall_pfn >= nr_pages )
+            goto error_out;
+        op.u.hypercall_init.domain = (domid_t)dom;
+        op.u.hypercall_init.mfn    = page_array[hypercall_pfn];
+        op.cmd = DOM0_HYPERCALL_INIT;
+        if ( xc_dom0_op(xc_handle, &op) )
+            goto error_out;
+    }
 
     free(mmu);
     free(page_array);
diff -r 246b6444c643 -r 71914b64b577 tools/libxc/xc_load_elf.c
--- a/tools/libxc/xc_load_elf.c Tue Jan 24 16:59:54 2006
+++ b/tools/libxc/xc_load_elf.c Tue Jan 24 17:05:45 2006
@@ -120,6 +120,7 @@
 
         break;
     }
+
     if ( guestinfo == NULL )
     {
 #ifdef __ia64__
@@ -129,6 +130,8 @@
         return -EINVAL;
 #endif
     }
+
+    dsi->xen_guest_string = guestinfo;
 
     for ( h = 0; h < ehdr->e_phnum; h++ ) 
     {
diff -r 246b6444c643 -r 71914b64b577 tools/libxc/xg_private.h
--- a/tools/libxc/xg_private.h  Tue Jan 24 16:59:54 2006
+++ b/tools/libxc/xg_private.h  Tue Jan 24 17:05:45 2006
@@ -136,6 +136,9 @@
     unsigned int  pae_kernel;
     unsigned long symtab_addr;
     unsigned long symtab_len;
+
+    /* __xen_guest info string for convenient loader parsing. */
+    char *xen_guest_string;
 };
 
 typedef int (*parseimagefunc)(char *image, unsigned long image_size,
diff -r 246b6444c643 -r 71914b64b577 xen/arch/x86/dom0_ops.c
--- a/xen/arch/x86/dom0_ops.c   Tue Jan 24 16:59:54 2006
+++ b/xen/arch/x86/dom0_ops.c   Tue Jan 24 17:05:45 2006
@@ -49,9 +49,6 @@
 long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
 {
     long ret = 0;
-
-    if ( !IS_PRIV(current->domain) )
-        return -EPERM;
 
     switch ( op->cmd )
     {
@@ -409,6 +406,35 @@
     }
     break;
 
+    case DOM0_HYPERCALL_INIT:
+    {
+        struct domain *d; 
+        unsigned long mfn = op->u.hypercall_init.mfn;
+        void *hypercall_page;
+
+        ret = -ESRCH;
+        if ( unlikely((d = find_domain_by_id(
+            op->u.hypercall_init.domain)) == NULL) )
+            break;
+
+        ret = -EACCES;
+        if ( !pfn_valid(mfn) ||
+             !get_page_and_type(pfn_to_page(mfn), d, PGT_writable_page) )
+        {
+            put_domain(d);
+            break;
+        }
+
+        ret = 0;
+
+        hypercall_page = map_domain_page(mfn);
+        hypercall_page_initialise(hypercall_page);
+        unmap_domain_page(hypercall_page);
+
+        put_domain(d);
+    }
+    break;
+
     default:
         ret = -ENOSYS;
         break;
diff -r 246b6444c643 -r 71914b64b577 xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Tue Jan 24 16:59:54 2006
+++ b/xen/arch/x86/domain_build.c       Tue Jan 24 17:05:45 2006
@@ -146,6 +146,8 @@
     struct pfn_info *page = NULL;
     start_info_t *si;
     struct vcpu *v = d->vcpu[0];
+    char *p;
+    unsigned long hypercall_page;
 #if defined(__i386__)
     char *image_start  = (char *)_image_start;  /* use lowmem mappings */
     char *initrd_start = (char *)_initrd_start; /* use lowmem mappings */
@@ -239,7 +241,8 @@
                xen_pae ? "yes" : "no", dom0_pae ? "yes" : "no");
         return -EINVAL;
     }
-    if (strstr(dsi.xen_section_string, "SHADOW=translate"))
+
+    if ( strstr(dsi.xen_section_string, "SHADOW=translate") )
         opt_dom0_translate = 1;
 
     /* Align load address to 4MB boundary. */
@@ -604,6 +607,23 @@
     /* Copy the OS image and free temporary buffer. */
     (void)loadelfimage(&dsi);
 
+    p = strstr(dsi.xen_section_string, "HYPERCALL_PAGE=");
+    if ( p != NULL )
+    {
+        p += strlen("HYPERCALL_PAGE=");
+        hypercall_page = simple_strtoul(p, NULL, 16);
+        hypercall_page = dsi.v_start + (hypercall_page << PAGE_SHIFT);
+        if ( (hypercall_page < dsi.v_start) || (hypercall_page >= v_end) )
+        {
+            write_ptbase(current);
+            local_irq_enable();
+            printk("Invalid HYPERCALL_PAGE field in guest header.\n");
+            return -1;
+        }
+
+        hypercall_page_initialise((void *)hypercall_page);
+    }
+
     init_domheap_pages(
         _image_start, (_image_start+image_len+PAGE_SIZE-1) & PAGE_MASK);
 
diff -r 246b6444c643 -r 71914b64b577 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c       Tue Jan 24 16:59:54 2006
+++ b/xen/arch/x86/x86_32/traps.c       Tue Jan 24 17:05:45 2006
@@ -298,6 +298,33 @@
     return 0;
 }
 
+void hypercall_page_initialise(void *hypercall_page)
+{
+    char *p;
+    int i;
+
+    /* Fill in all the transfer points with template machine code. */
+    for ( i = 0; i < (PAGE_SIZE / 32); i++ )
+    {
+        p = (char *)(hypercall_page + (i * 32));
+        *(u8  *)(p+ 0) = 0xb8;    /* mov  $<i>,%eax */
+        *(u32 *)(p+ 1) = i;
+        *(u16 *)(p+ 5) = 0x82cd;  /* int  $0x82 */
+        *(u8  *)(p+ 7) = 0xc3;    /* ret */
+    }
+
+    /*
+     * 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));
+    *(u8  *)(p+ 0) = 0x50;    /* push %eax */
+    *(u8  *)(p+ 1) = 0xb8;    /* mov  $__HYPERVISOR_iret,%eax */
+    *(u32 *)(p+ 2) = __HYPERVISOR_iret;
+    *(u16 *)(p+ 6) = 0x82cd;  /* int  $0x82 */
+}
+
 /*
  * Local variables:
  * mode: C
diff -r 246b6444c643 -r 71914b64b577 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c       Tue Jan 24 16:59:54 2006
+++ b/xen/arch/x86/x86_64/traps.c       Tue Jan 24 17:05:45 2006
@@ -268,6 +268,39 @@
     return 0;
 }
 
+void hypercall_page_initialise(void *hypercall_page)
+{
+    char *p;
+    int i;
+
+    /* Fill in all the transfer points with template machine code. */
+    for ( i = 0; i < (PAGE_SIZE / 32); i++ )
+    {
+        p = (char *)(hypercall_page + (i * 32));
+        *(u8  *)(p+ 0) = 0x51;    /* push %rcx */
+        *(u16 *)(p+ 1) = 0x5341;  /* push %r11 */
+        *(u8  *)(p+ 3) = 0xb8;    /* mov  $<i>,%eax */
+        *(u32 *)(p+ 4) = i;
+        *(u16 *)(p+ 8) = 0x050f;  /* syscall */
+        *(u16 *)(p+10) = 0x5b41;  /* pop  %r11 */
+        *(u8  *)(p+12) = 0x59;    /* pop  %rcx */
+        *(u8  *)(p+13) = 0xc3;    /* ret */
+    }
+
+    /*
+     * 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));
+    *(u8  *)(p+ 0) = 0x50;    /* push %rax */
+    *(u8  *)(p+ 1) = 0x51;    /* push %rcx */
+    *(u16 *)(p+ 2) = 0x5341;  /* push %r11 */
+    *(u8  *)(p+ 4) = 0xb8;    /* mov  $__HYPERVISOR_iret,%eax */
+    *(u32 *)(p+ 5) = __HYPERVISOR_iret;
+    *(u16 *)(p+ 9) = 0x050f;  /* syscall */
+}
+
 /*
  * Local variables:
  * mode: C
diff -r 246b6444c643 -r 71914b64b577 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Tue Jan 24 16:59:54 2006
+++ b/xen/include/asm-x86/domain.h      Tue Jan 24 17:05:45 2006
@@ -50,6 +50,12 @@
 
 /* x86/64: toggle guest between kernel and user modes. */
 extern void toggle_guest_mode(struct vcpu *);
+
+/*
+ * Initialise a hypercall-transfer page. The given pointer must be mapped
+ * in Xen virtual address space (accesses are not validated or checked).
+ */
+extern void hypercall_page_initialise(void *);
 
 struct arch_domain
 {
diff -r 246b6444c643 -r 71914b64b577 xen/include/public/dom0_ops.h
--- a/xen/include/public/dom0_ops.h     Tue Jan 24 16:59:54 2006
+++ b/xen/include/public/dom0_ops.h     Tue Jan 24 17:05:45 2006
@@ -424,6 +424,12 @@
     unsigned long nr_pfns;    /* number of pages in range (>0) */
     uint8_t allow_access;     /* allow (!0) or deny (0) access to range? */
 } dom0_iomem_permission_t;
+ 
+#define DOM0_HYPERCALL_INIT   48
+typedef struct {
+    domid_t  domain;          /* domain to be affected */
+    unsigned long mfn;        /* machine frame to be initialised */
+} dom0_hypercall_init_t;
  
 typedef struct {
     uint32_t cmd;
@@ -465,6 +471,7 @@
         dom0_setdebugging_t      setdebugging;
         dom0_irq_permission_t    irq_permission;
         dom0_iomem_permission_t  iomem_permission;
+        dom0_hypercall_init_t    hypercall_init;
         uint8_t                  pad[128];
     } u;
 } dom0_op_t;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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