WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Indirect hypercalls through a hypercall transfer page.
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 25 Jan 2006 13:58:08 +0000
Delivery-date: Wed, 25 Jan 2006 14:07:37 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Indirect hypercalls through a hypercall transfer page., Xen patchbot -unstable <=