direct-io.hg

changeset 14349:1721f90e1422

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@xensource.com>
author kfraser@localhost.localdomain
date Mon Mar 12 11:15:56 2007 +0000 (2007-03-12)
parents f9fbcc354daa
children f3f5f2756d75
files tools/firmware/hvmloader/hvmloader.c xen/arch/x86/hvm/svm/svm.c xen/include/asm-x86/hvm/svm/vmmcall.h
line diff
     1.1 --- a/tools/firmware/hvmloader/hvmloader.c	Mon Mar 12 11:04:34 2007 +0000
     1.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Mon Mar 12 11:15:56 2007 +0000
     1.3 @@ -38,23 +38,47 @@
     1.4  #define VMXASSIST_PHYSICAL_ADDRESS    0x000D0000
     1.5  #define ROMBIOS_PHYSICAL_ADDRESS      0x000F0000
     1.6  
     1.7 -/* invoke SVM's paged realmode support */
     1.8 -#define SVM_VMMCALL_RESET_TO_REALMODE 0x80000001
     1.9 -
    1.10 -/*
    1.11 - * C runtime start off
    1.12 - */
    1.13  asm(
    1.14      "    .text                       \n"
    1.15      "    .globl _start               \n"
    1.16      "_start:                         \n"
    1.17 +    /* C runtime kickoff. */
    1.18      "    cld                         \n"
    1.19      "    cli                         \n"
    1.20 +    "    movl $stack_top,%esp        \n"
    1.21 +    "    movl %esp,%ebp              \n"
    1.22 +    "    call main                   \n"
    1.23 +    /* Relocate real-mode trampoline to 0x0. */
    1.24 +    "    mov  $trampoline_start,%esi \n"
    1.25 +    "    xor  %edi,%edi              \n"
    1.26 +    "    mov  $trampoline_end,%ecx   \n"
    1.27 +    "    sub  %esi,%ecx              \n"
    1.28 +    "    rep  movsb                  \n"
    1.29 +    /* Load real-mode compatible segment state (base 0x0000, limit 0xffff). */
    1.30      "    lgdt gdt_desr               \n"
    1.31 -    "    movl $stack_top, %esp       \n"
    1.32 -    "    movl %esp, %ebp             \n"
    1.33 -    "    call main                   \n"
    1.34 -    "    ud2                         \n"
    1.35 +    "    mov  $0x0010,%ax            \n"
    1.36 +    "    mov  %ax,%ds                \n"
    1.37 +    "    mov  %ax,%es                \n"
    1.38 +    "    mov  %ax,%fs                \n"
    1.39 +    "    mov  %ax,%gs                \n"
    1.40 +    "    mov  %ax,%ss                \n"
    1.41 +    "    ljmp $0x8,$0x0              \n"
    1.42 +    /* Enter real mode, reload all segment registers and IDT. */
    1.43 +    "trampoline_start: .code16       \n"
    1.44 +    "    mov  %cr0,%eax              \n"
    1.45 +    "    and  $0xfe,%al              \n"
    1.46 +    "    mov  %eax,%cr0              \n"
    1.47 +    "    ljmp $0,$1f-trampoline_start\n"
    1.48 +    "1:  xor  %ax,%ax                \n"
    1.49 +    "    mov  %ax,%ds                \n"
    1.50 +    "    mov  %ax,%es                \n"
    1.51 +    "    mov  %ax,%fs                \n"
    1.52 +    "    mov  %ax,%gs                \n"
    1.53 +    "    mov  %ax,%ss                \n"
    1.54 +    "    lidt 1f-trampoline_start    \n"
    1.55 +    "    ljmp $0xf000,$0xfff0        \n"
    1.56 +    "1:  .word 0x3ff,0,0             \n"
    1.57 +    "trampoline_end:   .code32       \n"
    1.58      "                                \n"
    1.59      "gdt_desr:                       \n"
    1.60      "    .word gdt_end - gdt - 1     \n"
    1.61 @@ -63,8 +87,8 @@ asm(
    1.62      "    .align 8                    \n"
    1.63      "gdt:                            \n"
    1.64      "    .quad 0x0000000000000000    \n"
    1.65 -    "    .quad 0x00CF92000000FFFF    \n"
    1.66 -    "    .quad 0x00CF9A000000FFFF    \n"
    1.67 +    "    .quad 0x00009a000000ffff    \n" /* Ring 0 code, base 0 limit 0xffff */
    1.68 +    "    .quad 0x000092000000ffff    \n" /* Ring 0 data, base 0 limit 0xffff */
    1.69      "gdt_end:                        \n"
    1.70      "                                \n"
    1.71      "    .bss                        \n"
    1.72 @@ -84,19 +108,6 @@ cirrus_check(void)
    1.73  }
    1.74  
    1.75  static int
    1.76 -vmmcall(int function, int edi, int esi, int edx, int ecx, int ebx)
    1.77 -{
    1.78 -    int eax;
    1.79 -
    1.80 -    __asm__ __volatile__ (
    1.81 -        ".byte 0x0F,0x01,0xD9"
    1.82 -        : "=a" (eax)
    1.83 -        : "a"(function),
    1.84 -        "b"(ebx), "c"(ecx), "d"(edx), "D"(edi), "S"(esi) );
    1.85 -    return eax;
    1.86 -}
    1.87 -
    1.88 -static int
    1.89  check_amd(void)
    1.90  {
    1.91      char id[12];
    1.92 @@ -349,13 +360,7 @@ int main(void)
    1.93          ASSERT((ACPI_PHYSICAL_ADDRESS + acpi_sz) <= 0xF0000);
    1.94      }
    1.95  
    1.96 -    if ( check_amd() )
    1.97 -    {
    1.98 -        /* AMD implies this is SVM */
    1.99 -        printf("SVM go ...\n");
   1.100 -        vmmcall(SVM_VMMCALL_RESET_TO_REALMODE, 0, 0, 0, 0, 0);
   1.101 -    }
   1.102 -    else
   1.103 +    if ( !check_amd() )
   1.104      {
   1.105          printf("Loading VMXAssist ...\n");
   1.106          memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
   1.107 @@ -368,7 +373,7 @@ int main(void)
   1.108              );
   1.109      }
   1.110  
   1.111 -    printf("Failed to invoke ROMBIOS\n");
   1.112 +    printf("Invoking ROMBIOS ...\n");
   1.113      return 0;
   1.114  }
   1.115  
     2.1 --- a/xen/arch/x86/hvm/svm/svm.c	Mon Mar 12 11:04:34 2007 +0000
     2.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Mon Mar 12 11:15:56 2007 +0000
     2.3 @@ -43,7 +43,6 @@
     2.4  #include <asm/hvm/svm/svm.h>
     2.5  #include <asm/hvm/svm/vmcb.h>
     2.6  #include <asm/hvm/svm/emulate.h>
     2.7 -#include <asm/hvm/svm/vmmcall.h>
     2.8  #include <asm/hvm/svm/intr.h>
     2.9  #include <asm/x86_emulate.h>
    2.10  #include <public/sched.h>
    2.11 @@ -2591,65 +2590,6 @@ static int svm_do_vmmcall_reset_to_realm
    2.12  }
    2.13  
    2.14  
    2.15 -/*
    2.16 - * svm_do_vmmcall - SVM VMMCALL handler
    2.17 - *
    2.18 - * returns 0 on success, non-zero otherwise
    2.19 - */
    2.20 -static int svm_do_vmmcall(struct vcpu *v, struct cpu_user_regs *regs)
    2.21 -{
    2.22 -    struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
    2.23 -    int inst_len;
    2.24 -
    2.25 -    ASSERT(vmcb);
    2.26 -    ASSERT(regs);
    2.27 -
    2.28 -    inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
    2.29 -    ASSERT(inst_len > 0);
    2.30 -
    2.31 -    HVMTRACE_1D(VMMCALL, v, regs->eax);
    2.32 -
    2.33 -    if ( regs->eax & 0x80000000 )
    2.34 -    {
    2.35 -        /* VMMCALL sanity check */
    2.36 -        if ( vmcb->cpl > get_vmmcall_cpl(regs->edi) )
    2.37 -        {
    2.38 -            printk("VMMCALL CPL check failed\n");
    2.39 -            return -1;
    2.40 -        }
    2.41 -
    2.42 -        /* handle the request */
    2.43 -        switch ( regs->eax )
    2.44 -        {
    2.45 -        case VMMCALL_RESET_TO_REALMODE:
    2.46 -            if ( svm_do_vmmcall_reset_to_realmode(v, regs) )
    2.47 -            {
    2.48 -                printk("svm_do_vmmcall_reset_to_realmode() failed\n");
    2.49 -                return -1;
    2.50 -            }
    2.51 -            /* since we just reset the VMCB, return without adjusting
    2.52 -             * the eip */
    2.53 -            return 0;
    2.54 -
    2.55 -        case VMMCALL_DEBUG:
    2.56 -            printk("DEBUG features not implemented yet\n");
    2.57 -            break;
    2.58 -        default:
    2.59 -            break;
    2.60 -        }
    2.61 -
    2.62 -        hvm_print_line(v, regs->eax); /* provides the current domain */
    2.63 -    }
    2.64 -    else
    2.65 -    {
    2.66 -        hvm_do_hypercall(regs);
    2.67 -    }
    2.68 -
    2.69 -    __update_guest_eip(vmcb, inst_len);
    2.70 -    return 0;
    2.71 -}
    2.72 -
    2.73 -
    2.74  void svm_dump_inst(unsigned long eip)
    2.75  {
    2.76      u8 opcode[256];
    2.77 @@ -3152,9 +3092,14 @@ asmlinkage void svm_vmexit_handler(struc
    2.78          svm_handle_invlpg(1, regs);
    2.79          break;
    2.80  
    2.81 -    case VMEXIT_VMMCALL:
    2.82 -        svm_do_vmmcall(v, regs);
    2.83 +    case VMEXIT_VMMCALL: {
    2.84 +        int inst_len = __get_instruction_length(v, INSTR_VMCALL, NULL);
    2.85 +        ASSERT(inst_len > 0);
    2.86 +        HVMTRACE_1D(VMMCALL, v, regs->eax);
    2.87 +        __update_guest_eip(vmcb, inst_len);
    2.88 +        hvm_do_hypercall(regs);
    2.89          break;
    2.90 +    }
    2.91  
    2.92      case VMEXIT_CR0_READ:
    2.93          svm_cr_access(v, 0, TYPE_MOV_FROM_CR, regs);
     3.1 --- a/xen/include/asm-x86/hvm/svm/vmmcall.h	Mon Mar 12 11:04:34 2007 +0000
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,44 +0,0 @@
     3.4 -/*
     3.5 - * vmmcall.h: VMMCALL instruction support
     3.6 - *
     3.7 - * Travis Betak, travis.betak@amd.com
     3.8 - * Copyright (c) 2005, AMD Corporation.
     3.9 - *
    3.10 - * This program is free software; you can redistribute it and/or modify it
    3.11 - * under the terms and conditions of the GNU General Public License,
    3.12 - * version 2, as published by the Free Software Foundation.
    3.13 - *
    3.14 - * This program is distributed in the hope it will be useful, but WITHOUT
    3.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    3.16 - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    3.17 - * more details.
    3.18 - *
    3.19 - * You should have received a copy of the GNU General Public License along with
    3.20 - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    3.21 - * Place - Suite 330, Boston, MA 02111-1307 USA.
    3.22 - *
    3.23 - */
    3.24 -
    3.25 -#ifndef __ASM_X86_HVM_SVM_VMMCALL_H__
    3.26 -#define __ASM_X86_HVM_SVM_VMMCALL_H__
    3.27 -
    3.28 -/* VMMCALL command fields */
    3.29 -#define VMMCALL_CODE_CPL_MASK     0x60000000
    3.30 -#define VMMCALL_CODE_MBZ_MASK     0x1FFF0000
    3.31 -#define VMMCALL_CODE_COMMAND_MASK 0x0000FFFF
    3.32 -
    3.33 -#define MAKE_VMMCALL_CODE(cpl,func) ((cpl << 29) | (func) | 0x80000000)
    3.34 -
    3.35 -/* CPL=0 VMMCALL Requests */
    3.36 -#define VMMCALL_RESET_TO_REALMODE   MAKE_VMMCALL_CODE(0,1)
    3.37 -
    3.38 -/* CPL=3 VMMCALL Requests */
    3.39 -#define VMMCALL_DEBUG           MAKE_VMMCALL_CODE(3,1)
    3.40 -
    3.41 -/* return the cpl required for the vmmcall cmd */
    3.42 -static inline int get_vmmcall_cpl(int cmd)
    3.43 -{
    3.44 -    return (cmd & VMMCALL_CODE_CPL_MASK) >> 29;
    3.45 -}
    3.46 -
    3.47 -#endif /* __ASM_X86_HVM_SVM_VMMCALL_H__ */