ia64/xen-unstable
changeset 10976:49dcd838b7df
[HVMLOADER] HVM loader initialises hypercall shim and uses
it to interrogate Xen version information. Also add support
for HVM hypercall execution on 64-bit host.
Signed-off-by: Steven Smith <ssmith@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
it to interrogate Xen version information. Also add support
for HVM hypercall execution on 64-bit host.
Signed-off-by: Steven Smith <ssmith@xensource.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kfraser@localhost.localdomain |
---|---|
date | Fri Aug 04 20:30:12 2006 +0100 (2006-08-04) |
parents | 7684f9032f9f |
children | ffa5b2975dff |
files | tools/firmware/Makefile tools/firmware/hvmloader/Makefile tools/firmware/hvmloader/acpi_madt.c tools/firmware/hvmloader/hvmloader.c tools/firmware/hvmloader/hypercall.h tools/firmware/hvmloader/mp_tables.c tools/firmware/hvmloader/util.c tools/firmware/hvmloader/util.h xen/arch/x86/hvm/hvm.c xen/arch/x86/hvm/platform.c xen/common/kernel.c xen/include/asm-x86/guest_access.h xen/include/asm-x86/hvm/guest_access.h xen/include/public/version.h |
line diff
1.1 --- a/tools/firmware/Makefile Fri Aug 04 16:07:58 2006 +0100 1.2 +++ b/tools/firmware/Makefile Fri Aug 04 20:30:12 2006 +0100 1.3 @@ -30,7 +30,7 @@ all: 1.4 .PHONY: install 1.5 install: all 1.6 [ -d $(INSTALL_DIR) ] || install -d -m0755 $(INSTALL_DIR) 1.7 - [ ! -e $(TARGET) ] || install -m0644 $(TARGET) $(INSTALL_DIR) 1.8 + install -m0644 $(TARGET) $(INSTALL_DIR) 1.9 1.10 .PHONY: clean 1.11 clean:
2.1 --- a/tools/firmware/hvmloader/Makefile Fri Aug 04 16:07:58 2006 +0100 2.2 +++ b/tools/firmware/hvmloader/Makefile Fri Aug 04 20:30:12 2006 +0100 2.3 @@ -42,12 +42,15 @@ OBJCOPY = objcopy 2.4 CFLAGS += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float 2.5 LDFLAGS = -m32 -nostdlib -Wl,-N -Wl,-Ttext -Wl,$(LOADADDR) 2.6 2.7 +SRCS = hvmloader.c acpi_madt.c mp_tables.c util.c 2.8 +OBJS = $(patsubst %.c,%.o,$(SRCS)) 2.9 + 2.10 .PHONY: all 2.11 all: hvmloader 2.12 2.13 -hvmloader: roms.h hvmloader.c acpi_madt.c mp_tables.c 2.14 - $(CC) $(CFLAGS) -c hvmloader.c acpi_madt.c mp_tables.c 2.15 - $(CC) $(LDFLAGS) -o hvmloader.tmp hvmloader.o acpi_madt.o mp_tables.o 2.16 +hvmloader: roms.h $(SRCS) 2.17 + $(CC) $(CFLAGS) -c $(SRCS) 2.18 + $(CC) $(LDFLAGS) -o hvmloader.tmp $(OBJS) 2.19 $(OBJCOPY) hvmloader.tmp hvmloader 2.20 rm -f hvmloader.tmp 2.21
3.1 --- a/tools/firmware/hvmloader/acpi_madt.c Fri Aug 04 16:07:58 2006 +0100 3.2 +++ b/tools/firmware/hvmloader/acpi_madt.c Fri Aug 04 20:30:12 2006 +0100 3.3 @@ -20,13 +20,11 @@ 3.4 3.5 #include "../acpi/acpi2_0.h" 3.6 #include "../acpi/acpi_madt.h" 3.7 - 3.8 +#include "util.h" 3.9 #include <xen/hvm/hvm_info_table.h> 3.10 3.11 #define NULL ((void*)0) 3.12 3.13 -extern int puts(const char *s); 3.14 - 3.15 static struct hvm_info_table *table = NULL; 3.16 3.17 static int validate_hvm_info(struct hvm_info_table *t)
4.1 --- a/tools/firmware/hvmloader/hvmloader.c Fri Aug 04 16:07:58 2006 +0100 4.2 +++ b/tools/firmware/hvmloader/hvmloader.c Fri Aug 04 20:30:12 2006 +0100 4.3 @@ -23,9 +23,13 @@ 4.4 */ 4.5 #include "roms.h" 4.6 #include "../acpi/acpi2_0.h" /* for ACPI_PHYSICAL_ADDRESS */ 4.7 +#include "hypercall.h" 4.8 +#include "util.h" 4.9 +#include <xen/version.h> 4.10 #include <xen/hvm/hvm_info_table.h> 4.11 4.12 /* memory map */ 4.13 +#define HYPERCALL_PHYSICAL_ADDRESS 0x00080000 4.14 #define VGABIOS_PHYSICAL_ADDRESS 0x000C0000 4.15 #define VMXASSIST_PHYSICAL_ADDRESS 0x000D0000 4.16 #define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000 4.17 @@ -75,65 +79,14 @@ extern int acpi_madt_update(unsigned cha 4.18 extern void create_mp_tables(void); 4.19 struct hvm_info_table *get_hvm_info_table(void); 4.20 4.21 -static inline void 4.22 -outw(unsigned short addr, unsigned short val) 4.23 -{ 4.24 - __asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val)); 4.25 -} 4.26 - 4.27 -static inline void 4.28 -outb(unsigned short addr, unsigned char val) 4.29 -{ 4.30 - __asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val)); 4.31 -} 4.32 - 4.33 -static inline unsigned char 4.34 -inb(unsigned short addr) 4.35 -{ 4.36 - unsigned char val; 4.37 - 4.38 - __asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr)); 4.39 - return val; 4.40 -} 4.41 - 4.42 -void * 4.43 -memcpy(void *dest, const void *src, unsigned n) 4.44 -{ 4.45 - int t0, t1, t2; 4.46 - 4.47 - __asm__ __volatile__( 4.48 - "cld\n" 4.49 - "rep; movsl\n" 4.50 - "testb $2,%b4\n" 4.51 - "je 1f\n" 4.52 - "movsw\n" 4.53 - "1: testb $1,%b4\n" 4.54 - "je 2f\n" 4.55 - "movsb\n" 4.56 - "2:" 4.57 - : "=&c" (t0), "=&D" (t1), "=&S" (t2) 4.58 - : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src) 4.59 - : "memory" 4.60 - ); 4.61 - return dest; 4.62 -} 4.63 - 4.64 -int 4.65 -puts(const char *s) 4.66 -{ 4.67 - while (*s) 4.68 - outb(0xE9, *s++); 4.69 - return 0; 4.70 -} 4.71 - 4.72 -int 4.73 +static int 4.74 cirrus_check(void) 4.75 { 4.76 outw(0x3C4, 0x9206); 4.77 return inb(0x3C5) == 0x12; 4.78 } 4.79 4.80 -int 4.81 +static int 4.82 vmmcall(int function, int edi, int esi, int edx, int ecx, int ebx) 4.83 { 4.84 int eax; 4.85 @@ -147,7 +100,7 @@ vmmcall(int function, int edi, int esi, 4.86 return eax; 4.87 } 4.88 4.89 -int 4.90 +static int 4.91 check_amd(void) 4.92 { 4.93 char id[12]; 4.94 @@ -162,6 +115,60 @@ check_amd(void) 4.95 return __builtin_memcmp(id, "AuthenticAMD", 12) == 0; 4.96 } 4.97 4.98 +static void 4.99 +cpuid(uint32_t idx, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) 4.100 +{ 4.101 + __asm__ __volatile__( 4.102 + "cpuid" 4.103 + : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) 4.104 + : "0" (idx) ); 4.105 +} 4.106 + 4.107 +static void 4.108 +wrmsr(uint32_t idx, uint64_t v) 4.109 +{ 4.110 + __asm__ __volatile__( 4.111 + "wrmsr" 4.112 + : : "c" (idx), "a" ((uint32_t)v), "d" ((uint32_t)(v>>32)) ); 4.113 +} 4.114 + 4.115 +static void 4.116 +init_hypercalls(void) 4.117 +{ 4.118 + uint32_t eax, ebx, ecx, edx; 4.119 + unsigned long i; 4.120 + char signature[13], number[13]; 4.121 + xen_extraversion_t extraversion; 4.122 + 4.123 + cpuid(0x40000000, &eax, &ebx, &ecx, &edx); 4.124 + 4.125 + *(uint32_t *)(signature + 0) = ebx; 4.126 + *(uint32_t *)(signature + 4) = ecx; 4.127 + *(uint32_t *)(signature + 8) = edx; 4.128 + signature[12] = '\0'; 4.129 + 4.130 + if (strcmp("XenVMMXenVMM", signature) || (eax < 0x40000002)) { 4.131 + puts("FATAL: Xen hypervisor not detected\n"); 4.132 + __asm__ __volatile__( "ud2" ); 4.133 + } 4.134 + 4.135 + cpuid(0x40000001, &eax, &ebx, &ecx, &edx); 4.136 + 4.137 + puts("Detected Xen v"); 4.138 + puts(itoa(number, eax >> 16)); 4.139 + puts("."); 4.140 + puts(itoa(number, eax & 0xffff)); 4.141 + 4.142 + cpuid(0x40000002, &eax, &ebx, &ecx, &edx); 4.143 + 4.144 + for (i = 0; i < eax; i++) 4.145 + wrmsr(ebx, HYPERCALL_PHYSICAL_ADDRESS + (i << 12) + i); 4.146 + 4.147 + hypercall_xen_version(XENVER_extraversion, extraversion); 4.148 + puts(extraversion); 4.149 + puts("\n"); 4.150 +} 4.151 + 4.152 int 4.153 main(void) 4.154 { 4.155 @@ -169,6 +176,8 @@ main(void) 4.156 4.157 puts("HVM Loader\n"); 4.158 4.159 + init_hypercalls(); 4.160 + 4.161 puts("Loading ROMBIOS ...\n"); 4.162 memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios)); 4.163 if (t->apic_enabled)
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/tools/firmware/hvmloader/hypercall.h Fri Aug 04 20:30:12 2006 +0100 5.3 @@ -0,0 +1,180 @@ 5.4 +/****************************************************************************** 5.5 + * hypercall.h 5.6 + * 5.7 + * Copyright (c) 2002-2006, K A Fraser 5.8 + * 5.9 + * This program is free software; you can redistribute it and/or 5.10 + * modify it under the terms of the GNU General Public License version 2 5.11 + * as published by the Free Software Foundation; or, when distributed 5.12 + * separately from the Linux kernel or incorporated into other 5.13 + * software packages, subject to the following license: 5.14 + * 5.15 + * Permission is hereby granted, free of charge, to any person obtaining a copy 5.16 + * of this source file (the "Software"), to deal in the Software without 5.17 + * restriction, including without limitation the rights to use, copy, modify, 5.18 + * merge, publish, distribute, sublicense, and/or sell copies of the Software, 5.19 + * and to permit persons to whom the Software is furnished to do so, subject to 5.20 + * the following conditions: 5.21 + * 5.22 + * The above copyright notice and this permission notice shall be included in 5.23 + * all copies or substantial portions of the Software. 5.24 + * 5.25 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 5.26 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 5.27 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 5.28 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 5.29 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 5.30 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 5.31 + * IN THE SOFTWARE. 5.32 + */ 5.33 + 5.34 +#ifndef __HVMLOADER_HYPERCALL_H__ 5.35 +#define __HVMLOADER_HYPERCALL_H__ 5.36 + 5.37 +/* 5.38 + * NB. Hypercall address needs to be relative to a linkage symbol for 5.39 + * some version of ld to relocate the relative calls properly. 5.40 + * Keep this in sync with HYPERCALL_PHYSICAL_ADDRESS in hvmloader.c! 5.41 + */ 5.42 +#define hypercall_pa "_start - 0x80000" 5.43 + 5.44 +#define __STR(x) #x 5.45 +#define STR(x) __STR(x) 5.46 + 5.47 +#define _hypercall0(type, name) \ 5.48 +({ \ 5.49 + long __res; \ 5.50 + asm volatile ( \ 5.51 + "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \ 5.52 + : "=a" (__res) \ 5.53 + : \ 5.54 + : "memory" ); \ 5.55 + (type)__res; \ 5.56 +}) 5.57 + 5.58 +#define _hypercall1(type, name, a1) \ 5.59 +({ \ 5.60 + long __res, __ign1; \ 5.61 + asm volatile ( \ 5.62 + "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \ 5.63 + : "=a" (__res), "=b" (__ign1) \ 5.64 + : "1" ((long)(a1)) \ 5.65 + : "memory" ); \ 5.66 + (type)__res; \ 5.67 +}) 5.68 + 5.69 +#define _hypercall2(type, name, a1, a2) \ 5.70 +({ \ 5.71 + long __res, __ign1, __ign2; \ 5.72 + asm volatile ( \ 5.73 + "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \ 5.74 + : "=a" (__res), "=b" (__ign1), "=c" (__ign2) \ 5.75 + : "1" ((long)(a1)), "2" ((long)(a2)) \ 5.76 + : "memory" ); \ 5.77 + (type)__res; \ 5.78 +}) 5.79 + 5.80 +#define _hypercall3(type, name, a1, a2, a3) \ 5.81 +({ \ 5.82 + long __res, __ign1, __ign2, __ign3; \ 5.83 + asm volatile ( \ 5.84 + "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \ 5.85 + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ 5.86 + "=d" (__ign3) \ 5.87 + : "1" ((long)(a1)), "2" ((long)(a2)), \ 5.88 + "3" ((long)(a3)) \ 5.89 + : "memory" ); \ 5.90 + (type)__res; \ 5.91 +}) 5.92 + 5.93 +#define _hypercall4(type, name, a1, a2, a3, a4) \ 5.94 +({ \ 5.95 + long __res, __ign1, __ign2, __ign3, __ign4; \ 5.96 + asm volatile ( \ 5.97 + "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \ 5.98 + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ 5.99 + "=d" (__ign3), "=S" (__ign4) \ 5.100 + : "1" ((long)(a1)), "2" ((long)(a2)), \ 5.101 + "3" ((long)(a3)), "4" ((long)(a4)) \ 5.102 + : "memory" ); \ 5.103 + (type)__res; \ 5.104 +}) 5.105 + 5.106 +#define _hypercall5(type, name, a1, a2, a3, a4, a5) \ 5.107 +({ \ 5.108 + long __res, __ign1, __ign2, __ign3, __ign4, __ign5; \ 5.109 + asm volatile ( \ 5.110 + "call "hypercall_pa" + " STR(__HYPERVISOR_##name * 32) \ 5.111 + : "=a" (__res), "=b" (__ign1), "=c" (__ign2), \ 5.112 + "=d" (__ign3), "=S" (__ign4), "=D" (__ign5) \ 5.113 + : "1" ((long)(a1)), "2" ((long)(a2)), \ 5.114 + "3" ((long)(a3)), "4" ((long)(a4)), \ 5.115 + "5" ((long)(a5)) \ 5.116 + : "memory" ); \ 5.117 + (type)__res; \ 5.118 +}) 5.119 + 5.120 +static inline int 5.121 +hypercall_sched_op( 5.122 + int cmd, void *arg) 5.123 +{ 5.124 + return _hypercall2(int, sched_op, cmd, arg); 5.125 +} 5.126 + 5.127 +static inline int 5.128 +hypercall_memory_op( 5.129 + unsigned int cmd, void *arg) 5.130 +{ 5.131 + return _hypercall2(int, memory_op, cmd, arg); 5.132 +} 5.133 + 5.134 +static inline int 5.135 +hypercall_multicall( 5.136 + void *call_list, int nr_calls) 5.137 +{ 5.138 + return _hypercall2(int, multicall, call_list, nr_calls); 5.139 +} 5.140 + 5.141 +static inline int 5.142 +hypercall_event_channel_op( 5.143 + int cmd, void *arg) 5.144 +{ 5.145 + return _hypercall2(int, event_channel_op, cmd, arg); 5.146 +} 5.147 + 5.148 +static inline int 5.149 +hypercall_xen_version( 5.150 + int cmd, void *arg) 5.151 +{ 5.152 + return _hypercall2(int, xen_version, cmd, arg); 5.153 +} 5.154 + 5.155 +static inline int 5.156 +hypercall_console_io( 5.157 + int cmd, int count, char *str) 5.158 +{ 5.159 + return _hypercall3(int, console_io, cmd, count, str); 5.160 +} 5.161 + 5.162 +static inline int 5.163 +hypercall_vm_assist( 5.164 + unsigned int cmd, unsigned int type) 5.165 +{ 5.166 + return _hypercall2(int, vm_assist, cmd, type); 5.167 +} 5.168 + 5.169 +static inline int 5.170 +hypercall_vcpu_op( 5.171 + int cmd, int vcpuid, void *extra_args) 5.172 +{ 5.173 + return _hypercall3(int, vcpu_op, cmd, vcpuid, extra_args); 5.174 +} 5.175 + 5.176 +static inline int 5.177 +hypercall_hvm_op( 5.178 + int cmd, void *arg) 5.179 +{ 5.180 + return _hypercall2(int, hvm_op, cmd, arg); 5.181 +} 5.182 + 5.183 +#endif /* __HVMLOADER_HYPERCALL_H__ */
6.1 --- a/tools/firmware/hvmloader/mp_tables.c Fri Aug 04 16:07:58 2006 +0100 6.2 +++ b/tools/firmware/hvmloader/mp_tables.c Fri Aug 04 20:30:12 2006 +0100 6.3 @@ -93,7 +93,8 @@ typedef signed long int64_t; 6.4 6.5 #define INTR_MAX_NR 16 6.6 6.7 -extern int puts(const char *); /* for printing */ 6.8 +#include "util.h" 6.9 + 6.10 extern int get_vcpu_nr(void); /* for the guest's VCPU count */ 6.11 6.12 /*
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/tools/firmware/hvmloader/util.c Fri Aug 04 20:30:12 2006 +0100 7.3 @@ -0,0 +1,96 @@ 7.4 +/* 7.5 + * util.c: Helper library functions for HVMLoader. 7.6 + * 7.7 + * Leendert van Doorn, leendert@watson.ibm.com 7.8 + * Copyright (c) 2005, International Business Machines Corporation. 7.9 + * 7.10 + * This program is free software; you can redistribute it and/or modify it 7.11 + * under the terms and conditions of the GNU General Public License, 7.12 + * version 2, as published by the Free Software Foundation. 7.13 + * 7.14 + * This program is distributed in the hope it will be useful, but WITHOUT 7.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 7.17 + * more details. 7.18 + * 7.19 + * You should have received a copy of the GNU General Public License along with 7.20 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 7.21 + * Place - Suite 330, Boston, MA 02111-1307 USA. 7.22 + */ 7.23 + 7.24 +#include "../acpi/acpi2_0.h" /* for ACPI_PHYSICAL_ADDRESS */ 7.25 +#include "util.h" 7.26 + 7.27 +void outw(uint16_t addr, uint16_t val) 7.28 +{ 7.29 + __asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val)); 7.30 +} 7.31 + 7.32 +void outb(uint16_t addr, uint8_t val) 7.33 +{ 7.34 + __asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val)); 7.35 +} 7.36 + 7.37 +uint8_t inb(uint16_t addr) 7.38 +{ 7.39 + uint8_t val; 7.40 + __asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr)); 7.41 + return val; 7.42 +} 7.43 + 7.44 +char *itoa(char *a, unsigned int i) 7.45 +{ 7.46 + unsigned int _i = i, x = 0; 7.47 + 7.48 + do { 7.49 + x++; 7.50 + _i /= 10; 7.51 + } while (_i != 0); 7.52 + 7.53 + a += x; 7.54 + *a-- = '\0'; 7.55 + 7.56 + do { 7.57 + *a-- = (i % 10) + '0'; 7.58 + i /= 10; 7.59 + } while (i != 0); 7.60 + 7.61 + return a + 1; 7.62 +} 7.63 + 7.64 +int strcmp(const char *cs, const char *ct) 7.65 +{ 7.66 + signed char res; 7.67 + 7.68 + while (((res = *cs - *ct++) == 0) && (*cs++ != '\0')) 7.69 + continue; 7.70 + 7.71 + return res; 7.72 +} 7.73 + 7.74 +void *memcpy(void *dest, const void *src, unsigned n) 7.75 +{ 7.76 + int t0, t1, t2; 7.77 + 7.78 + __asm__ __volatile__( 7.79 + "cld\n" 7.80 + "rep; movsl\n" 7.81 + "testb $2,%b4\n" 7.82 + "je 1f\n" 7.83 + "movsw\n" 7.84 + "1: testb $1,%b4\n" 7.85 + "je 2f\n" 7.86 + "movsb\n" 7.87 + "2:" 7.88 + : "=&c" (t0), "=&D" (t1), "=&S" (t2) 7.89 + : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src) 7.90 + : "memory" 7.91 + ); 7.92 + return dest; 7.93 +} 7.94 + 7.95 +void puts(const char *s) 7.96 +{ 7.97 + while (*s) 7.98 + outb(0xE9, *s++); 7.99 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/tools/firmware/hvmloader/util.h Fri Aug 04 20:30:12 2006 +0100 8.3 @@ -0,0 +1,19 @@ 8.4 +#ifndef __HVMLOADER_UTIL_H__ 8.5 +#define __HVMLOADER_UTIL_H__ 8.6 + 8.7 +/* I/O output */ 8.8 +void outw(uint16_t addr, uint16_t val); 8.9 +void outb(uint16_t addr, uint8_t val); 8.10 + 8.11 +/* I/O input */ 8.12 +uint8_t inb(uint16_t addr); 8.13 + 8.14 +/* String and memory functions */ 8.15 +int strcmp(const char *cs, const char *ct); 8.16 +void *memcpy(void *dest, const void *src, unsigned n); 8.17 +char *itoa(char *a, unsigned int i); 8.18 + 8.19 +/* Debug output */ 8.20 +void puts(const char *s); 8.21 + 8.22 +#endif /* __HVMLOADER_UTIL_H__ */
9.1 --- a/xen/arch/x86/hvm/hvm.c Fri Aug 04 16:07:58 2006 +0100 9.2 +++ b/xen/arch/x86/hvm/hvm.c Fri Aug 04 20:30:12 2006 +0100 9.3 @@ -28,6 +28,7 @@ 9.4 #include <xen/domain.h> 9.5 #include <xen/domain_page.h> 9.6 #include <xen/hypercall.h> 9.7 +#include <xen/guest_access.h> 9.8 #include <asm/current.h> 9.9 #include <asm/io.h> 9.10 #include <asm/shadow.h> 9.11 @@ -46,7 +47,8 @@ 9.12 #include <public/sched.h> 9.13 #include <public/hvm/ioreq.h> 9.14 #include <public/hvm/hvm_info_table.h> 9.15 -#include <xen/guest_access.h> 9.16 +#include <public/version.h> 9.17 +#include <public/memory.h> 9.18 9.19 int hvm_enabled = 0; 9.20 9.21 @@ -305,55 +307,139 @@ void hvm_print_line(struct vcpu *v, cons 9.22 pbuf[(*index)++] = c; 9.23 } 9.24 9.25 -#if defined(__i386__) 9.26 - 9.27 typedef unsigned long hvm_hypercall_t( 9.28 unsigned long, unsigned long, unsigned long, unsigned long, unsigned long); 9.29 -#define HYPERCALL(x) [ __HYPERVISOR_ ## x ] = (hvm_hypercall_t *) do_ ## x 9.30 + 9.31 +#define HYPERCALL(x) \ 9.32 + [ __HYPERVISOR_ ## x ] = (hvm_hypercall_t *) do_ ## x 9.33 +#define HYPERCALL_COMPAT32(x) \ 9.34 + [ __HYPERVISOR_ ## x ] = (hvm_hypercall_t *) do_ ## x ## _compat32 9.35 + 9.36 +#if defined(__i386__) 9.37 + 9.38 static hvm_hypercall_t *hvm_hypercall_table[] = { 9.39 - HYPERCALL(mmu_update), 9.40 HYPERCALL(memory_op), 9.41 HYPERCALL(multicall), 9.42 - HYPERCALL(update_va_mapping), 9.43 - HYPERCALL(event_channel_op_compat), 9.44 HYPERCALL(xen_version), 9.45 - HYPERCALL(grant_table_op), 9.46 HYPERCALL(event_channel_op), 9.47 HYPERCALL(hvm_op) 9.48 }; 9.49 -#undef HYPERCALL 9.50 9.51 void hvm_do_hypercall(struct cpu_user_regs *pregs) 9.52 { 9.53 - if ( ring_3(pregs) ) 9.54 + if ( unlikely(ring_3(pregs)) ) 9.55 { 9.56 pregs->eax = -EPERM; 9.57 return; 9.58 } 9.59 9.60 - if ( pregs->eax > ARRAY_SIZE(hvm_hypercall_table) || 9.61 - !hvm_hypercall_table[pregs->eax] ) 9.62 + if ( (pregs->eax >= NR_hypercalls) || !hvm_hypercall_table[pregs->eax] ) 9.63 { 9.64 DPRINTK("HVM vcpu %d:%d did a bad hypercall %d.\n", 9.65 current->domain->domain_id, current->vcpu_id, 9.66 pregs->eax); 9.67 pregs->eax = -ENOSYS; 9.68 + return; 9.69 + } 9.70 + 9.71 + pregs->eax = hvm_hypercall_table[pregs->eax]( 9.72 + pregs->ebx, pregs->ecx, pregs->edx, pregs->esi, pregs->edi); 9.73 +} 9.74 + 9.75 +#else /* defined(__x86_64__) */ 9.76 + 9.77 +static long do_memory_op_compat32(int cmd, XEN_GUEST_HANDLE(void) arg) 9.78 +{ 9.79 + extern long do_add_to_physmap(struct xen_add_to_physmap *xatp); 9.80 + long rc; 9.81 + 9.82 + switch ( cmd ) 9.83 + { 9.84 + case XENMEM_add_to_physmap: 9.85 + { 9.86 + struct { 9.87 + domid_t domid; 9.88 + uint32_t space; 9.89 + uint32_t idx; 9.90 + uint32_t gpfn; 9.91 + } u; 9.92 + struct xen_add_to_physmap h; 9.93 + 9.94 + if ( copy_from_guest(&u, arg, 1) ) 9.95 + return -EFAULT; 9.96 + 9.97 + h.domid = u.domid; 9.98 + h.space = u.space; 9.99 + h.idx = u.idx; 9.100 + h.gpfn = u.gpfn; 9.101 + 9.102 + this_cpu(guest_handles_in_xen_space) = 1; 9.103 + rc = do_memory_op(cmd, guest_handle_from_ptr(&h, void)); 9.104 + this_cpu(guest_handles_in_xen_space) = 0; 9.105 + 9.106 + break; 9.107 + } 9.108 + 9.109 + default: 9.110 + DPRINTK("memory_op %d.\n", cmd); 9.111 + rc = -ENOSYS; 9.112 + break; 9.113 + } 9.114 + 9.115 + return rc; 9.116 +} 9.117 + 9.118 +static hvm_hypercall_t *hvm_hypercall64_table[NR_hypercalls] = { 9.119 + HYPERCALL(memory_op), 9.120 + HYPERCALL(xen_version), 9.121 + HYPERCALL(hvm_op), 9.122 + HYPERCALL(event_channel_op) 9.123 +}; 9.124 + 9.125 +static hvm_hypercall_t *hvm_hypercall32_table[NR_hypercalls] = { 9.126 + HYPERCALL_COMPAT32(memory_op), 9.127 + HYPERCALL(xen_version), 9.128 + HYPERCALL(hvm_op), 9.129 + HYPERCALL(event_channel_op) 9.130 +}; 9.131 + 9.132 +void hvm_do_hypercall(struct cpu_user_regs *pregs) 9.133 +{ 9.134 + if ( unlikely(ring_3(pregs)) ) 9.135 + { 9.136 + pregs->rax = -EPERM; 9.137 + return; 9.138 + } 9.139 + 9.140 + pregs->rax = (uint32_t)pregs->eax; /* mask in case compat32 caller */ 9.141 + if ( (pregs->rax >= NR_hypercalls) || !hvm_hypercall64_table[pregs->rax] ) 9.142 + { 9.143 + DPRINTK("HVM vcpu %d:%d did a bad hypercall %ld.\n", 9.144 + current->domain->domain_id, current->vcpu_id, 9.145 + pregs->rax); 9.146 + pregs->rax = -ENOSYS; 9.147 + return; 9.148 + } 9.149 + 9.150 + if ( current->domain->arch.ops->guest_paging_levels == PAGING_L4 ) 9.151 + { 9.152 + pregs->rax = hvm_hypercall64_table[pregs->rax](pregs->rdi, 9.153 + pregs->rsi, 9.154 + pregs->rdx, 9.155 + pregs->r10, 9.156 + pregs->r8); 9.157 } 9.158 else 9.159 { 9.160 - pregs->eax = hvm_hypercall_table[pregs->eax]( 9.161 - pregs->ebx, pregs->ecx, pregs->edx, pregs->esi, pregs->edi); 9.162 + pregs->eax = hvm_hypercall32_table[pregs->eax]((uint32_t)pregs->ebx, 9.163 + (uint32_t)pregs->ecx, 9.164 + (uint32_t)pregs->edx, 9.165 + (uint32_t)pregs->esi, 9.166 + (uint32_t)pregs->edi); 9.167 } 9.168 } 9.169 9.170 -#else /* __x86_64__ */ 9.171 - 9.172 -void hvm_do_hypercall(struct cpu_user_regs *pregs) 9.173 -{ 9.174 - printk("not supported yet!\n"); 9.175 -} 9.176 - 9.177 -#endif 9.178 +#endif /* defined(__x86_64__) */ 9.179 9.180 /* Initialise a hypercall transfer page for a VMX domain using 9.181 paravirtualised drivers. */
10.1 --- a/xen/arch/x86/hvm/platform.c Fri Aug 04 16:07:58 2006 +0100 10.2 +++ b/xen/arch/x86/hvm/platform.c Fri Aug 04 20:30:12 2006 +0100 10.3 @@ -1034,17 +1034,31 @@ void handle_mmio(unsigned long va, unsig 10.4 } 10.5 } 10.6 10.7 +DEFINE_PER_CPU(int, guest_handles_in_xen_space); 10.8 + 10.9 /* Note that copy_{to,from}_user_hvm don't set the A and D bits on 10.10 PTEs, and require the PTE to be writable even when they're only 10.11 trying to read from it. The guest is expected to deal with 10.12 this. */ 10.13 unsigned long copy_to_user_hvm(void *to, const void *from, unsigned len) 10.14 { 10.15 + if ( this_cpu(guest_handles_in_xen_space) ) 10.16 + { 10.17 + memcpy(to, from, len); 10.18 + return 0; 10.19 + } 10.20 + 10.21 return !hvm_copy((void *)from, (unsigned long)to, len, HVM_COPY_OUT); 10.22 } 10.23 10.24 unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len) 10.25 { 10.26 + if ( this_cpu(guest_handles_in_xen_space) ) 10.27 + { 10.28 + memcpy(to, from, len); 10.29 + return 0; 10.30 + } 10.31 + 10.32 return !hvm_copy(to, (unsigned long)from, len, HVM_COPY_IN); 10.33 } 10.34
11.1 --- a/xen/common/kernel.c Fri Aug 04 16:07:58 2006 +0100 11.2 +++ b/xen/common/kernel.c Fri Aug 04 20:30:12 2006 +0100 11.3 @@ -217,6 +217,13 @@ long do_xen_version(int cmd, XEN_GUEST_H 11.4 return (!guest_handle_is_null(arg) ? -EINVAL : PAGE_SIZE); 11.5 } 11.6 11.7 + case XENVER_guest_handle: 11.8 + { 11.9 + if ( copy_to_guest(arg, (char *)current->domain->handle, 11.10 + sizeof(current->domain->handle)) ) 11.11 + return -EFAULT; 11.12 + return 0; 11.13 + } 11.14 } 11.15 11.16 return -ENOSYS;
12.1 --- a/xen/include/asm-x86/guest_access.h Fri Aug 04 16:07:58 2006 +0100 12.2 +++ b/xen/include/asm-x86/guest_access.h Fri Aug 04 20:30:12 2006 +0100 12.3 @@ -20,9 +20,12 @@ 12.4 /* Cast a guest handle to the specified type of handle. */ 12.5 #define guest_handle_cast(hnd, type) ({ \ 12.6 type *_x = (hnd).p; \ 12.7 - (XEN_GUEST_HANDLE(type)) { _x }; \ 12.8 + (XEN_GUEST_HANDLE(type)) { _x }; \ 12.9 }) 12.10 12.11 +#define guest_handle_from_ptr(ptr, type) \ 12.12 + ((XEN_GUEST_HANDLE(type)) { (type *)ptr }) 12.13 + 12.14 /* 12.15 * Copy an array of objects to guest context via a guest handle, 12.16 * specifying an offset into the guest array.
13.1 --- a/xen/include/asm-x86/hvm/guest_access.h Fri Aug 04 16:07:58 2006 +0100 13.2 +++ b/xen/include/asm-x86/hvm/guest_access.h Fri Aug 04 20:30:12 2006 +0100 13.3 @@ -1,6 +1,9 @@ 13.4 #ifndef __ASM_X86_HVM_GUEST_ACCESS_H__ 13.5 #define __ASM_X86_HVM_GUEST_ACCESS_H__ 13.6 13.7 +#include <xen/percpu.h> 13.8 +DECLARE_PER_CPU(int, guest_handles_in_xen_space); 13.9 + 13.10 unsigned long copy_to_user_hvm(void *to, const void *from, unsigned len); 13.11 unsigned long copy_from_user_hvm(void *to, const void *from, unsigned len); 13.12
14.1 --- a/xen/include/public/version.h Fri Aug 04 16:07:58 2006 +0100 14.2 +++ b/xen/include/public/version.h Fri Aug 04 20:30:12 2006 +0100 14.3 @@ -57,6 +57,9 @@ typedef struct xen_feature_info xen_feat 14.4 /* arg == NULL; returns host memory page size. */ 14.5 #define XENVER_pagesize 7 14.6 14.7 +/* arg == xen_domain_handle_t. */ 14.8 +#define XENVER_guest_handle 8 14.9 + 14.10 #endif /* __XEN_PUBLIC_VERSION_H__ */ 14.11 14.12 /*