# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1173698156 0
# Node ID 1721f90e14220beda99ae5f68aef8eb411eaf5c7
# Parent f9fbcc354daaa0bf8d19fa90a29f5de8f920c95f
AMD HVM: Exit hvmloader via a normal jump-to-realmode code sequence.
Strip out all SVM-special hypercall code.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
---
xen/include/asm-x86/hvm/svm/vmmcall.h | 44 ---------------------
tools/firmware/hvmloader/hvmloader.c | 71 ++++++++++++++++++----------------
xen/arch/x86/hvm/svm/svm.c | 71 +++-------------------------------
3 files changed, 46 insertions(+), 140 deletions(-)
diff -r f9fbcc354daa -r 1721f90e1422 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c Mon Mar 12 11:04:34 2007 +0000
+++ b/tools/firmware/hvmloader/hvmloader.c Mon Mar 12 11:15:56 2007 +0000
@@ -38,23 +38,47 @@
#define VMXASSIST_PHYSICAL_ADDRESS 0x000D0000
#define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000
-/* invoke SVM's paged realmode support */
-#define SVM_VMMCALL_RESET_TO_REALMODE 0x80000001
-
-/*
- * C runtime start off
- */
asm(
" .text \n"
" .globl _start \n"
"_start: \n"
+ /* C runtime kickoff. */
" cld \n"
" cli \n"
+ " movl $stack_top,%esp \n"
+ " movl %esp,%ebp \n"
+ " call main \n"
+ /* Relocate real-mode trampoline to 0x0. */
+ " mov $trampoline_start,%esi \n"
+ " xor %edi,%edi \n"
+ " mov $trampoline_end,%ecx \n"
+ " sub %esi,%ecx \n"
+ " rep movsb \n"
+ /* Load real-mode compatible segment state (base 0x0000, limit 0xffff). */
" lgdt gdt_desr \n"
- " movl $stack_top, %esp \n"
- " movl %esp, %ebp \n"
- " call main \n"
- " ud2 \n"
+ " mov $0x0010,%ax \n"
+ " mov %ax,%ds \n"
+ " mov %ax,%es \n"
+ " mov %ax,%fs \n"
+ " mov %ax,%gs \n"
+ " mov %ax,%ss \n"
+ " ljmp $0x8,$0x0 \n"
+ /* Enter real mode, reload all segment registers and IDT. */
+ "trampoline_start: .code16 \n"
+ " mov %cr0,%eax \n"
+ " and $0xfe,%al \n"
+ " mov %eax,%cr0 \n"
+ " ljmp $0,$1f-trampoline_start\n"
+ "1: xor %ax,%ax \n"
+ " mov %ax,%ds \n"
+ " mov %ax,%es \n"
+ " mov %ax,%fs \n"
+ " mov %ax,%gs \n"
+ " mov %ax,%ss \n"
+ " lidt 1f-trampoline_start \n"
+ " ljmp $0xf000,$0xfff0 \n"
+ "1: .word 0x3ff,0,0 \n"
+ "trampoline_end: .code32 \n"
" \n"
"gdt_desr: \n"
" .word gdt_end - gdt - 1 \n"
@@ -63,8 +87,8 @@ asm(
" .align 8 \n"
"gdt: \n"
" .quad 0x0000000000000000 \n"
- " .quad 0x00CF92000000FFFF \n"
- " .quad 0x00CF9A000000FFFF \n"
+ " .quad 0x00009a000000ffff \n" /* Ring 0 code, base 0 limit 0xffff */
+ " .quad 0x000092000000ffff \n" /* Ring 0 data, base 0 limit 0xffff */
"gdt_end: \n"
" \n"
" .bss \n"
@@ -81,19 +105,6 @@ cirrus_check(void)
{
outw(0x3C4, 0x9206);
return inb(0x3C5) == 0x12;
-}
-
-static int
-vmmcall(int function, int edi, int esi, int edx, int ecx, int ebx)
-{
- int eax;
-
- __asm__ __volatile__ (
- ".byte 0x0F,0x01,0xD9"
- : "=a" (eax)
- : "a"(function),
- "b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi) );
- return eax;
}
static int
@@ -349,13 +360,7 @@ int main(void)
ASSERT((ACPI_PHYSICAL_ADDRESS + acpi_sz) <= 0xF0000);
}
- if ( check_amd() )
- {
- /* AMD implies this is SVM */
- printf("SVM go ...\n");
- vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0);
- }
- else
+ if ( !check_amd() )
{
printf("Loading VMXAssist ...\n");
memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
@@ -368,7 +373,7 @@ int main(void)
);
}
- printf("Failed to invoke ROMBIOS\n");
+ printf("Invoking ROMBIOS ...\n");
return 0;
}
diff -r f9fbcc354daa -r 1721f90e1422 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Mon Mar 12 11:04:34 2007 +0000
+++ b/xen/arch/x86/hvm/svm/svm.c Mon Mar 12 11:15:56 2007 +0000
@@ -43,7 +43,6 @@
#include <asm/hvm/svm/svm.h>
#include <asm/hvm/svm/vmcb.h>
#include <asm/hvm/svm/emulate.h>
-#include <asm/hvm/svm/vmmcall.h>
#include <asm/hvm/svm/intr.h>
#include <asm/x86_emulate.h>
#include <public/sched.h>
@@ -2587,65 +2586,6 @@ static int svm_do_vmmcall_reset_to_realm
vmcb->rax = 0;
vmcb->rsp = 0;
- return 0;
-}
-
-
-/*
- * svm_do_vmmcall - SVM VMMCALL handler
- *
- * returns 0 on success, non-zero otherwise
- */
-static int svm_do_vmmcall(struct vcpu *v, struct cpu_user_regs *regs)
-{
- struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- int inst_len;
-
- ASSERT(vmcb);
- ASSERT(regs);
-
- inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
- ASSERT(inst_len > 0);
-
- HVMTRACE_1D(VMMCALL, v, regs->eax);
-
- if ( regs->eax & 0x80000000 )
- {
- /* VMMCALL sanity check */
- if ( vmcb->cpl > get_vmmcall_cpl(regs->edi) )
- {
- printk("VMMCALL CPL check failed\n");
- return -1;
- }
-
- /* handle the request */
- switch ( regs->eax )
- {
- case VMMCALL_RESET_TO_REALMODE:
- if ( svm_do_vmmcall_reset_to_realmode(v, regs) )
- {
- printk("svm_do_vmmcall_reset_to_realmode() failed\n");
- return -1;
- }
- /* since we just reset the VMCB, return without adjusting
- * the eip */
- return 0;
-
- case VMMCALL_DEBUG:
- printk("DEBUG features not implemented yet\n");
- break;
- default:
- break;
- }
-
- hvm_print_line(v, regs->eax); /* provides the current domain */
- }
- else
- {
- hvm_do_hypercall(regs);
- }
-
- __update_guest_eip(vmcb, inst_len);
return 0;
}
@@ -3152,9 +3092,14 @@ asmlinkage void svm_vmexit_handler(struc
svm_handle_invlpg(1, regs);
break;
- case VMEXIT_VMMCALL:
- svm_do_vmmcall(v, regs);
- break;
+ case VMEXIT_VMMCALL: {
+ int inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
+ ASSERT(inst_len > 0);
+ HVMTRACE_1D(VMMCALL, v, regs->eax);
+ __update_guest_eip(vmcb, inst_len);
+ hvm_do_hypercall(regs);
+ break;
+ }
case VMEXIT_CR0_READ:
svm_cr_access(v, 0, TYPE_MOV_FROM_CR, regs);
diff -r f9fbcc354daa -r 1721f90e1422 xen/include/asm-x86/hvm/svm/vmmcall.h
--- a/xen/include/asm-x86/hvm/svm/vmmcall.h Mon Mar 12 11:04:34 2007 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * vmmcall.h: VMMCALL instruction support
- *
- * Travis Betak, travis.betak@xxxxxxx
- * Copyright (c) 2005, AMD Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- */
-
-#ifndef __ASM_X86_HVM_SVM_VMMCALL_H__
-#define __ASM_X86_HVM_SVM_VMMCALL_H__
-
-/* VMMCALL command fields */
-#define VMMCALL_CODE_CPL_MASK 0x60000000
-#define VMMCALL_CODE_MBZ_MASK 0x1FFF0000
-#define VMMCALL_CODE_COMMAND_MASK 0x0000FFFF
-
-#define MAKE_VMMCALL_CODE(cpl,func) ((cpl << 29) | (func) | 0x80000000)
-
-/* CPL=0 VMMCALL Requests */
-#define VMMCALL_RESET_TO_REALMODE MAKE_VMMCALL_CODE(0,1)
-
-/* CPL=3 VMMCALL Requests */
-#define VMMCALL_DEBUG MAKE_VMMCALL_CODE(3,1)
-
-/* return the cpl required for the vmmcall cmd */
-static inline int get_vmmcall_cpl(int cmd)
-{
- return (cmd & VMMCALL_CODE_CPL_MASK) >> 29;
-}
-
-#endif /* __ASM_X86_HVM_SVM_VMMCALL_H__ */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|