ia64/xen-unstable
changeset 8651:71914b64b577
Indirect hypercalls through a hypercall transfer page.
Signed-off-by: Keir Fraser <keir@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
line diff
1.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Tue Jan 24 17:59:54 2006 +0100 1.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/entry.S Tue Jan 24 18:05:45 2006 +0100 1.3 @@ -333,10 +333,8 @@ iret_exc: 1.4 hypervisor_iret: 1.5 andl $~NMI_MASK, EFLAGS(%esp) 1.6 RESTORE_REGS 1.7 - movl %eax,(%esp) 1.8 - movl $__HYPERVISOR_iret,%eax 1.9 - int $0x82 1.10 - ud2 1.11 + addl $4, %esp 1.12 + jmp hypercall_page + (__HYPERVISOR_iret * 32) 1.13 1.14 #if 0 /* XEN */ 1.15 ldt_ss:
2.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S Tue Jan 24 17:59:54 2006 +0100 2.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S Tue Jan 24 18:05:45 2006 +0100 2.3 @@ -5,6 +5,7 @@ 2.4 .ascii "GUEST_OS=linux,GUEST_VER=2.6" 2.5 .ascii ",XEN_VER=xen-3.0" 2.6 .ascii ",VIRT_BASE=0xC0000000" 2.7 + .ascii ",HYPERCALL_PAGE=0x104" /* __pa(hypercall_page) >> 12 */ 2.8 #ifdef CONFIG_X86_PAE 2.9 .ascii ",PAE=yes" 2.10 #else 2.11 @@ -187,6 +188,9 @@ ENTRY(cpu_gdt_table) 2.12 ENTRY(default_ldt) 2.13 2.14 .org 0x4000 2.15 +ENTRY(hypercall_page) 2.16 + 2.17 +.org 0x5000 2.18 /* 2.19 * Real beginning of normal "text" segment 2.20 */
3.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S Tue Jan 24 17:59:54 2006 +0100 3.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/entry.S Tue Jan 24 18:05:45 2006 +0100 3.3 @@ -127,15 +127,10 @@ 3.4 * }; 3.5 * #define VGCF_IN_SYSCALL (1<<8) 3.6 */ 3.7 - .macro HYPERVISOR_IRET flag 3.8 - subq $8*4,%rsp # reuse rip, cs, rflags, rsp, ss in the stack 3.9 - movq %rax,(%rsp) 3.10 - movq %r11,1*8(%rsp) 3.11 - movq %rcx,2*8(%rsp) # we saved %rcx upon exceptions 3.12 - movq $\flag,3*8(%rsp) 3.13 - movq $__HYPERVISOR_iret,%rax 3.14 - syscall 3.15 - .endm 3.16 + .macro HYPERVISOR_IRET flag 3.17 + pushq $\flag 3.18 + jmp hypercall_page + (__HYPERVISOR_iret * 32) 3.19 + .endm 3.20 3.21 .macro SWITCH_TO_KERNEL ssoff,adjust=0 3.22 jc 1f
4.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S Tue Jan 24 17:59:54 2006 +0100 4.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/head.S Tue Jan 24 18:05:45 2006 +0100 4.3 @@ -16,9 +16,11 @@ 4.4 #include <linux/linkage.h> 4.5 4.6 .section __xen_guest 4.7 - .ascii "GUEST_OS=linux,GUEST_VER=2.6,XEN_VER=xen-3.0,VIRT_BASE=0xffffffff80000000" 4.8 + .ascii "GUEST_OS=linux,GUEST_VER=2.6" 4.9 + .ascii ",XEN_VER=xen-3.0" 4.10 + .ascii ",VIRT_BASE=0xffffffff80000000" 4.11 + .ascii ",HYPERCALL_PAGE=0x10d" /* __pa(hypercall_page) >> 12 */ 4.12 .ascii ",LOADER=generic" 4.13 -/* .ascii ",PT_MODE_WRITABLE" */ 4.14 .byte 0 4.15 4.16 4.17 @@ -227,8 +229,10 @@ ENTRY(empty_bad_pmd_table) 4.18 ENTRY(level3_physmem_pgt) 4.19 .quad 0x0000000000105007 /* -> level2_kernel_pgt (so that __va works even before pagetable_init) */ 4.20 4.21 - 4.22 - .org 0xd000 4.23 +.org 0xd000 4.24 +ENTRY(hypercall_page) 4.25 + 4.26 +.org 0xe000 4.27 #ifdef CONFIG_ACPI_SLEEP 4.28 ENTRY(wakeup_level4_pgt) 4.29 .quad 0x0000000000102007 /* -> level3_ident_pgt */
5.1 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Tue Jan 24 17:59:54 2006 +0100 5.2 +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Tue Jan 24 18:05:45 2006 +0100 5.3 @@ -58,7 +58,9 @@ static int privcmd_ioctl(struct inode *i 5.4 "movl 16(%%eax),%%esi ;" 5.5 "movl 20(%%eax),%%edi ;" 5.6 "movl (%%eax),%%eax ;" 5.7 - TRAP_INSTR "; " 5.8 + "shll $5,%%eax ;" 5.9 + "addl $hypercall_page,%%eax ;" 5.10 + "call *%%eax ;" 5.11 "popl %%edi; popl %%esi; popl %%edx; " 5.12 "popl %%ecx; popl %%ebx" 5.13 : "=a" (ret) : "0" (&hypercall) : "memory" ); 5.14 @@ -66,7 +68,10 @@ static int privcmd_ioctl(struct inode *i 5.15 { 5.16 long ign1, ign2, ign3; 5.17 __asm__ __volatile__ ( 5.18 - "movq %8,%%r10; movq %9,%%r8;" TRAP_INSTR 5.19 + "movq %8,%%r10; movq %9,%%r8;" 5.20 + "shlq $5,%%rax ;" 5.21 + "addq $hypercall_page,%%rax ;" 5.22 + "call *%%rax" 5.23 : "=a" (ret), "=D" (ign1), 5.24 "=S" (ign2), "=d" (ign3) 5.25 : "0" ((unsigned long)hypercall.op), 5.26 @@ -75,7 +80,7 @@ static int privcmd_ioctl(struct inode *i 5.27 "3" ((unsigned long)hypercall.arg[2]), 5.28 "g" ((unsigned long)hypercall.arg[3]), 5.29 "g" ((unsigned long)hypercall.arg[4]) 5.30 - : "r11","rcx","r8","r10","memory"); 5.31 + : "r8", "r10", "memory" ); 5.32 } 5.33 #elif defined (__ia64__) 5.34 __asm__ __volatile__ (
6.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Tue Jan 24 17:59:54 2006 +0100 6.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypercall.h Tue Jan 24 18:05:45 2006 +0100 6.3 @@ -34,13 +34,15 @@ 6.4 #include <asm-xen/xen-public/sched.h> 6.5 #include <asm-xen/xen-public/nmi.h> 6.6 6.7 +#define __STR(x) #x 6.8 +#define STR(x) __STR(x) 6.9 + 6.10 #define _hypercall0(type, name) \ 6.11 ({ \ 6.12 long __res; \ 6.13 asm volatile ( \ 6.14 - TRAP_INSTR \ 6.15 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ 6.16 : "=a" (__res) \ 6.17 - : "0" (__HYPERVISOR_##name) \ 6.18 : "memory" ); \ 6.19 (type)__res; \ 6.20 }) 6.21 @@ -49,9 +51,9 @@ 6.22 ({ \ 6.23 long __res, __ign1; \ 6.24 asm volatile ( \ 6.25 - TRAP_INSTR \ 6.26 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ 6.27 : "=a" (__res), "=b" (__ign1) \ 6.28 - : "0" (__HYPERVISOR_##name), "1" ((long)(a1)) \ 6.29 + : "1" ((long)(a1)) \ 6.30 : "memory" ); \ 6.31 (type)__res; \ 6.32 }) 6.33 @@ -60,10 +62,9 @@ 6.34 ({ \ 6.35 long __res, __ign1, __ign2; \ 6.36 asm volatile ( \ 6.37 - TRAP_INSTR \ 6.38 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ 6.39 : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \ 6.40 - : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ 6.41 - "2" ((long)(a2)) \ 6.42 + : "1" ((long)(a1)), "2" ((long)(a2)) \ 6.43 : "memory" ); \ 6.44 (type)__res; \ 6.45 }) 6.46 @@ -72,11 +73,11 @@ 6.47 ({ \ 6.48 long __res, __ign1, __ign2, __ign3; \ 6.49 asm volatile ( \ 6.50 - TRAP_INSTR \ 6.51 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ 6.52 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ 6.53 "=d" (__ign3) \ 6.54 - : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ 6.55 - "2" ((long)(a2)), "3" ((long)(a3)) \ 6.56 + : "1" ((long)(a1)), "2" ((long)(a2)), \ 6.57 + "3" ((long)(a3)) \ 6.58 : "memory" ); \ 6.59 (type)__res; \ 6.60 }) 6.61 @@ -85,12 +86,11 @@ 6.62 ({ \ 6.63 long __res, __ign1, __ign2, __ign3, __ign4; \ 6.64 asm volatile ( \ 6.65 - TRAP_INSTR \ 6.66 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ 6.67 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ 6.68 "=d" (__ign3), "=S" (__ign4) \ 6.69 - : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ 6.70 - "2" ((long)(a2)), "3" ((long)(a3)), \ 6.71 - "4" ((long)(a4)) \ 6.72 + : "1" ((long)(a1)), "2" ((long)(a2)), \ 6.73 + "3" ((long)(a3)), "4" ((long)(a4)) \ 6.74 : "memory" ); \ 6.75 (type)__res; \ 6.76 }) 6.77 @@ -99,12 +99,12 @@ 6.78 ({ \ 6.79 long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \ 6.80 asm volatile ( \ 6.81 - TRAP_INSTR \ 6.82 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ 6.83 : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ 6.84 "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \ 6.85 - : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ 6.86 - "2" ((long)(a2)), "3" ((long)(a3)), \ 6.87 - "4" ((long)(a4)), "5" ((long)(a5)) \ 6.88 + : "1" ((long)(a1)), "2" ((long)(a2)), \ 6.89 + "3" ((long)(a3)), "4" ((long)(a4)), \ 6.90 + "5" ((long)(a5)) \ 6.91 : "memory" ); \ 6.92 (type)__res; \ 6.93 })
7.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h Tue Jan 24 17:59:54 2006 +0100 7.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/hypercall.h Tue Jan 24 18:05:45 2006 +0100 7.3 @@ -37,16 +37,16 @@ 7.4 #include <asm-xen/xen-public/xen.h> 7.5 #include <asm-xen/xen-public/sched.h> 7.6 7.7 -#define __syscall_clobber "r11","rcx","memory" 7.8 +#define __STR(x) #x 7.9 +#define STR(x) __STR(x) 7.10 7.11 #define _hypercall0(type, name) \ 7.12 ({ \ 7.13 long __res; \ 7.14 asm volatile ( \ 7.15 - TRAP_INSTR \ 7.16 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ 7.17 : "=a" (__res) \ 7.18 - : "0" (__HYPERVISOR_##name) \ 7.19 - : __syscall_clobber ); \ 7.20 + : "memory" ); \ 7.21 (type)__res; \ 7.22 }) 7.23 7.24 @@ -54,10 +54,10 @@ 7.25 ({ \ 7.26 long __res, __ign1; \ 7.27 asm volatile ( \ 7.28 - TRAP_INSTR \ 7.29 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ 7.30 : "=a" (__res), "=D" (__ign1) \ 7.31 - : "0" (__HYPERVISOR_##name), "1" ((long)(a1)) \ 7.32 - : __syscall_clobber ); \ 7.33 + : "1" ((long)(a1)) \ 7.34 + : "memory" ); \ 7.35 (type)__res; \ 7.36 }) 7.37 7.38 @@ -65,11 +65,10 @@ 7.39 ({ \ 7.40 long __res, __ign1, __ign2; \ 7.41 asm volatile ( \ 7.42 - TRAP_INSTR \ 7.43 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ 7.44 : "=a" (__res), "=D" (__ign1), "=S" (__ign2) \ 7.45 - : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ 7.46 - "2" ((long)(a2)) \ 7.47 - : __syscall_clobber ); \ 7.48 + : "1" ((long)(a1)), "2" ((long)(a2)) \ 7.49 + : "memory" ); \ 7.50 (type)__res; \ 7.51 }) 7.52 7.53 @@ -77,12 +76,12 @@ 7.54 ({ \ 7.55 long __res, __ign1, __ign2, __ign3; \ 7.56 asm volatile ( \ 7.57 - TRAP_INSTR \ 7.58 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ 7.59 : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ 7.60 "=d" (__ign3) \ 7.61 - : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ 7.62 - "2" ((long)(a2)), "3" ((long)(a3)) \ 7.63 - : __syscall_clobber ); \ 7.64 + : "1" ((long)(a1)), "2" ((long)(a2)), \ 7.65 + "3" ((long)(a3)) \ 7.66 + : "memory" ); \ 7.67 (type)__res; \ 7.68 }) 7.69 7.70 @@ -90,13 +89,13 @@ 7.71 ({ \ 7.72 long __res, __ign1, __ign2, __ign3; \ 7.73 asm volatile ( \ 7.74 - "movq %8,%%r10; " TRAP_INSTR \ 7.75 + "movq %8,%%r10; " \ 7.76 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ 7.77 : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ 7.78 "=d" (__ign3) \ 7.79 - : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ 7.80 - "2" ((long)(a2)), "3" ((long)(a3)), \ 7.81 - "g" ((long)(a4)) \ 7.82 - : __syscall_clobber, "r10" ); \ 7.83 + : "1" ((long)(a1)), "2" ((long)(a2)), \ 7.84 + "3" ((long)(a3)), "g" ((long)(a4)) \ 7.85 + : "memory", "r10" ); \ 7.86 (type)__res; \ 7.87 }) 7.88 7.89 @@ -104,13 +103,14 @@ 7.90 ({ \ 7.91 long __res, __ign1, __ign2, __ign3; \ 7.92 asm volatile ( \ 7.93 - "movq %8,%%r10; movq %9,%%r8; " TRAP_INSTR \ 7.94 + "movq %8,%%r10; movq %9,%%r8; " \ 7.95 + "call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\ 7.96 : "=a" (__res), "=D" (__ign1), "=S" (__ign2), \ 7.97 "=d" (__ign3) \ 7.98 - : "0" (__HYPERVISOR_##name), "1" ((long)(a1)), \ 7.99 - "2" ((long)(a2)), "3" ((long)(a3)), \ 7.100 - "g" ((long)(a4)), "g" ((long)(a5)) \ 7.101 - : __syscall_clobber, "r10", "r8" ); \ 7.102 + : "1" ((long)(a1)), "2" ((long)(a2)), \ 7.103 + "3" ((long)(a3)), "g" ((long)(a4)), \ 7.104 + "g" ((long)(a5)) \ 7.105 + : "memory", "r10", "r8" ); \ 7.106 (type)__res; \ 7.107 }) 7.108
8.1 --- a/tools/libxc/xc_linux_build.c Tue Jan 24 17:59:54 2006 +0100 8.2 +++ b/tools/libxc/xc_linux_build.c Tue Jan 24 18:05:45 2006 +0100 8.3 @@ -429,10 +429,12 @@ static int setup_guest(int xc_handle, 8.4 unsigned int console_evtchn, unsigned long *console_mfn) 8.5 { 8.6 unsigned long *page_array = NULL; 8.7 - unsigned long count, i; 8.8 + unsigned long count, i, hypercall_pfn; 8.9 start_info_t *start_info; 8.10 shared_info_t *shared_info; 8.11 xc_mmu_t *mmu = NULL; 8.12 + char *p; 8.13 + DECLARE_DOM0_OP; 8.14 int rc; 8.15 8.16 unsigned long nr_pt_pages; 8.17 @@ -715,6 +717,20 @@ static int setup_guest(int xc_handle, 8.18 if ( xc_finish_mmu_updates(xc_handle, mmu) ) 8.19 goto error_out; 8.20 8.21 + p = strstr(dsi.xen_guest_string, "HYPERCALL_PAGE="); 8.22 + if ( p != NULL ) 8.23 + { 8.24 + p += strlen("HYPERCALL_PAGE="); 8.25 + hypercall_pfn = strtoul(p, NULL, 16); 8.26 + if ( hypercall_pfn >= nr_pages ) 8.27 + goto error_out; 8.28 + op.u.hypercall_init.domain = (domid_t)dom; 8.29 + op.u.hypercall_init.mfn = page_array[hypercall_pfn]; 8.30 + op.cmd = DOM0_HYPERCALL_INIT; 8.31 + if ( xc_dom0_op(xc_handle, &op) ) 8.32 + goto error_out; 8.33 + } 8.34 + 8.35 free(mmu); 8.36 free(page_array); 8.37
9.1 --- a/tools/libxc/xc_load_elf.c Tue Jan 24 17:59:54 2006 +0100 9.2 +++ b/tools/libxc/xc_load_elf.c Tue Jan 24 18:05:45 2006 +0100 9.3 @@ -120,6 +120,7 @@ static int parseelfimage(char *image, 9.4 9.5 break; 9.6 } 9.7 + 9.8 if ( guestinfo == NULL ) 9.9 { 9.10 #ifdef __ia64__ 9.11 @@ -130,6 +131,8 @@ static int parseelfimage(char *image, 9.12 #endif 9.13 } 9.14 9.15 + dsi->xen_guest_string = guestinfo; 9.16 + 9.17 for ( h = 0; h < ehdr->e_phnum; h++ ) 9.18 { 9.19 phdr = (Elf_Phdr *)(image + ehdr->e_phoff + (h*ehdr->e_phentsize));
10.1 --- a/tools/libxc/xg_private.h Tue Jan 24 17:59:54 2006 +0100 10.2 +++ b/tools/libxc/xg_private.h Tue Jan 24 18:05:45 2006 +0100 10.3 @@ -136,6 +136,9 @@ struct domain_setup_info 10.4 unsigned int pae_kernel; 10.5 unsigned long symtab_addr; 10.6 unsigned long symtab_len; 10.7 + 10.8 + /* __xen_guest info string for convenient loader parsing. */ 10.9 + char *xen_guest_string; 10.10 }; 10.11 10.12 typedef int (*parseimagefunc)(char *image, unsigned long image_size,
11.1 --- a/xen/arch/x86/dom0_ops.c Tue Jan 24 17:59:54 2006 +0100 11.2 +++ b/xen/arch/x86/dom0_ops.c Tue Jan 24 18:05:45 2006 +0100 11.3 @@ -50,9 +50,6 @@ long arch_do_dom0_op(dom0_op_t *op, dom0 11.4 { 11.5 long ret = 0; 11.6 11.7 - if ( !IS_PRIV(current->domain) ) 11.8 - return -EPERM; 11.9 - 11.10 switch ( op->cmd ) 11.11 { 11.12 11.13 @@ -409,6 +406,35 @@ long arch_do_dom0_op(dom0_op_t *op, dom0 11.14 } 11.15 break; 11.16 11.17 + case DOM0_HYPERCALL_INIT: 11.18 + { 11.19 + struct domain *d; 11.20 + unsigned long mfn = op->u.hypercall_init.mfn; 11.21 + void *hypercall_page; 11.22 + 11.23 + ret = -ESRCH; 11.24 + if ( unlikely((d = find_domain_by_id( 11.25 + op->u.hypercall_init.domain)) == NULL) ) 11.26 + break; 11.27 + 11.28 + ret = -EACCES; 11.29 + if ( !pfn_valid(mfn) || 11.30 + !get_page_and_type(pfn_to_page(mfn), d, PGT_writable_page) ) 11.31 + { 11.32 + put_domain(d); 11.33 + break; 11.34 + } 11.35 + 11.36 + ret = 0; 11.37 + 11.38 + hypercall_page = map_domain_page(mfn); 11.39 + hypercall_page_initialise(hypercall_page); 11.40 + unmap_domain_page(hypercall_page); 11.41 + 11.42 + put_domain(d); 11.43 + } 11.44 + break; 11.45 + 11.46 default: 11.47 ret = -ENOSYS; 11.48 break;
12.1 --- a/xen/arch/x86/domain_build.c Tue Jan 24 17:59:54 2006 +0100 12.2 +++ b/xen/arch/x86/domain_build.c Tue Jan 24 18:05:45 2006 +0100 12.3 @@ -146,6 +146,8 @@ int construct_dom0(struct domain *d, 12.4 struct pfn_info *page = NULL; 12.5 start_info_t *si; 12.6 struct vcpu *v = d->vcpu[0]; 12.7 + char *p; 12.8 + unsigned long hypercall_page; 12.9 #if defined(__i386__) 12.10 char *image_start = (char *)_image_start; /* use lowmem mappings */ 12.11 char *initrd_start = (char *)_initrd_start; /* use lowmem mappings */ 12.12 @@ -239,7 +241,8 @@ int construct_dom0(struct domain *d, 12.13 xen_pae ? "yes" : "no", dom0_pae ? "yes" : "no"); 12.14 return -EINVAL; 12.15 } 12.16 - if (strstr(dsi.xen_section_string, "SHADOW=translate")) 12.17 + 12.18 + if ( strstr(dsi.xen_section_string, "SHADOW=translate") ) 12.19 opt_dom0_translate = 1; 12.20 12.21 /* Align load address to 4MB boundary. */ 12.22 @@ -604,6 +607,23 @@ int construct_dom0(struct domain *d, 12.23 /* Copy the OS image and free temporary buffer. */ 12.24 (void)loadelfimage(&dsi); 12.25 12.26 + p = strstr(dsi.xen_section_string, "HYPERCALL_PAGE="); 12.27 + if ( p != NULL ) 12.28 + { 12.29 + p += strlen("HYPERCALL_PAGE="); 12.30 + hypercall_page = simple_strtoul(p, NULL, 16); 12.31 + hypercall_page = dsi.v_start + (hypercall_page << PAGE_SHIFT); 12.32 + if ( (hypercall_page < dsi.v_start) || (hypercall_page >= v_end) ) 12.33 + { 12.34 + write_ptbase(current); 12.35 + local_irq_enable(); 12.36 + printk("Invalid HYPERCALL_PAGE field in guest header.\n"); 12.37 + return -1; 12.38 + } 12.39 + 12.40 + hypercall_page_initialise((void *)hypercall_page); 12.41 + } 12.42 + 12.43 init_domheap_pages( 12.44 _image_start, (_image_start+image_len+PAGE_SIZE-1) & PAGE_MASK); 12.45
13.1 --- a/xen/arch/x86/x86_32/traps.c Tue Jan 24 17:59:54 2006 +0100 13.2 +++ b/xen/arch/x86/x86_32/traps.c Tue Jan 24 18:05:45 2006 +0100 13.3 @@ -298,6 +298,33 @@ long do_set_callbacks(unsigned long even 13.4 return 0; 13.5 } 13.6 13.7 +void hypercall_page_initialise(void *hypercall_page) 13.8 +{ 13.9 + char *p; 13.10 + int i; 13.11 + 13.12 + /* Fill in all the transfer points with template machine code. */ 13.13 + for ( i = 0; i < (PAGE_SIZE / 32); i++ ) 13.14 + { 13.15 + p = (char *)(hypercall_page + (i * 32)); 13.16 + *(u8 *)(p+ 0) = 0xb8; /* mov $<i>,%eax */ 13.17 + *(u32 *)(p+ 1) = i; 13.18 + *(u16 *)(p+ 5) = 0x82cd; /* int $0x82 */ 13.19 + *(u8 *)(p+ 7) = 0xc3; /* ret */ 13.20 + } 13.21 + 13.22 + /* 13.23 + * HYPERVISOR_iret is special because it doesn't return and expects a 13.24 + * special stack frame. Guests jump at this transfer point instead of 13.25 + * calling it. 13.26 + */ 13.27 + p = (char *)(hypercall_page + (__HYPERVISOR_iret * 32)); 13.28 + *(u8 *)(p+ 0) = 0x50; /* push %eax */ 13.29 + *(u8 *)(p+ 1) = 0xb8; /* mov $__HYPERVISOR_iret,%eax */ 13.30 + *(u32 *)(p+ 2) = __HYPERVISOR_iret; 13.31 + *(u16 *)(p+ 6) = 0x82cd; /* int $0x82 */ 13.32 +} 13.33 + 13.34 /* 13.35 * Local variables: 13.36 * mode: C
14.1 --- a/xen/arch/x86/x86_64/traps.c Tue Jan 24 17:59:54 2006 +0100 14.2 +++ b/xen/arch/x86/x86_64/traps.c Tue Jan 24 18:05:45 2006 +0100 14.3 @@ -268,6 +268,39 @@ long do_set_callbacks(unsigned long even 14.4 return 0; 14.5 } 14.6 14.7 +void hypercall_page_initialise(void *hypercall_page) 14.8 +{ 14.9 + char *p; 14.10 + int i; 14.11 + 14.12 + /* Fill in all the transfer points with template machine code. */ 14.13 + for ( i = 0; i < (PAGE_SIZE / 32); i++ ) 14.14 + { 14.15 + p = (char *)(hypercall_page + (i * 32)); 14.16 + *(u8 *)(p+ 0) = 0x51; /* push %rcx */ 14.17 + *(u16 *)(p+ 1) = 0x5341; /* push %r11 */ 14.18 + *(u8 *)(p+ 3) = 0xb8; /* mov $<i>,%eax */ 14.19 + *(u32 *)(p+ 4) = i; 14.20 + *(u16 *)(p+ 8) = 0x050f; /* syscall */ 14.21 + *(u16 *)(p+10) = 0x5b41; /* pop %r11 */ 14.22 + *(u8 *)(p+12) = 0x59; /* pop %rcx */ 14.23 + *(u8 *)(p+13) = 0xc3; /* ret */ 14.24 + } 14.25 + 14.26 + /* 14.27 + * HYPERVISOR_iret is special because it doesn't return and expects a 14.28 + * special stack frame. Guests jump at this transfer point instead of 14.29 + * calling it. 14.30 + */ 14.31 + p = (char *)(hypercall_page + (__HYPERVISOR_iret * 32)); 14.32 + *(u8 *)(p+ 0) = 0x50; /* push %rax */ 14.33 + *(u8 *)(p+ 1) = 0x51; /* push %rcx */ 14.34 + *(u16 *)(p+ 2) = 0x5341; /* push %r11 */ 14.35 + *(u8 *)(p+ 4) = 0xb8; /* mov $__HYPERVISOR_iret,%eax */ 14.36 + *(u32 *)(p+ 5) = __HYPERVISOR_iret; 14.37 + *(u16 *)(p+ 9) = 0x050f; /* syscall */ 14.38 +} 14.39 + 14.40 /* 14.41 * Local variables: 14.42 * mode: C
15.1 --- a/xen/include/asm-x86/domain.h Tue Jan 24 17:59:54 2006 +0100 15.2 +++ b/xen/include/asm-x86/domain.h Tue Jan 24 18:05:45 2006 +0100 15.3 @@ -51,6 +51,12 @@ extern void mapcache_init(struct domain 15.4 /* x86/64: toggle guest between kernel and user modes. */ 15.5 extern void toggle_guest_mode(struct vcpu *); 15.6 15.7 +/* 15.8 + * Initialise a hypercall-transfer page. The given pointer must be mapped 15.9 + * in Xen virtual address space (accesses are not validated or checked). 15.10 + */ 15.11 +extern void hypercall_page_initialise(void *); 15.12 + 15.13 struct arch_domain 15.14 { 15.15 l1_pgentry_t *mm_perdomain_pt;
16.1 --- a/xen/include/public/dom0_ops.h Tue Jan 24 17:59:54 2006 +0100 16.2 +++ b/xen/include/public/dom0_ops.h Tue Jan 24 18:05:45 2006 +0100 16.3 @@ -425,6 +425,12 @@ typedef struct { 16.4 uint8_t allow_access; /* allow (!0) or deny (0) access to range? */ 16.5 } dom0_iomem_permission_t; 16.6 16.7 +#define DOM0_HYPERCALL_INIT 48 16.8 +typedef struct { 16.9 + domid_t domain; /* domain to be affected */ 16.10 + unsigned long mfn; /* machine frame to be initialised */ 16.11 +} dom0_hypercall_init_t; 16.12 + 16.13 typedef struct { 16.14 uint32_t cmd; 16.15 uint32_t interface_version; /* DOM0_INTERFACE_VERSION */ 16.16 @@ -465,6 +471,7 @@ typedef struct { 16.17 dom0_setdebugging_t setdebugging; 16.18 dom0_irq_permission_t irq_permission; 16.19 dom0_iomem_permission_t iomem_permission; 16.20 + dom0_hypercall_init_t hypercall_init; 16.21 uint8_t pad[128]; 16.22 } u; 16.23 } dom0_op_t;