1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2019 Joyent, Inc.
  29  */
  30 
  31 #include <sys/asm_linkage.h>
  32 #ifndef __xpv
  33 #include <sys/xpv_support.h>
  34 #endif
  35 #include <sys/hypervisor.h>
  36 
  37 /*
  38  * Hypervisor "system calls"
  39  *
  40  * amd64
  41  *      %rax == call number
  42  *      args in registers (%rdi, %rsi, %rdx, %r10, %r8, %r9)
  43  *
  44  * Note that we use %r10 instead of %rcx for passing 4th argument as in
  45  * C calling convention since the "syscall" instruction clobbers %rcx.
  46  *
  47  * (These calls can be done more efficiently as gcc-style inlines, but
  48  * for simplicity and help with initial debugging, we use these primitives
  49  * to build the hypervisor calls up from C wrappers.)
  50  */
  51 
  52 /*
  53  * XXPV grr - assembler can't deal with an instruction in a quoted string
  54  */
  55 #undef  TRAP_INSTR      /* cause it's currently "int $0x82" */
  56 
  57 /*
  58  * The method for issuing a hypercall (i.e. a system call to the
  59  * hypervisor) varies from platform to platform.  In 32-bit PV domains, an
  60  * 'int 82' triggers the call.  In 64-bit PV domains, a 'syscall' does the
  61  * trick.
  62  *
  63  * HVM domains are more complicated.  In all cases, we want to issue a
  64  * VMEXIT instruction, but AMD and Intel use different opcodes to represent
  65  * that instruction.  Rather than build CPU-specific modules with the
  66  * different opcodes, we use the 'hypercall page' provided by Xen.  This
  67  * page contains a collection of code stubs that do nothing except issue
  68  * hypercalls using the proper instructions for this machine.  To keep the
  69  * wrapper code as simple and efficient as possible, we preallocate that
  70  * page below.  When the module is loaded, we ask Xen to remap the
  71  * underlying PFN to that of the hypercall page.
  72  *
  73  * Note: this same mechanism could be used in PV domains, but using
  74  * hypercall page requires a call and several more instructions than simply
  75  * issuing the proper trap.
  76  */
  77 #if !defined(__xpv)
  78 
  79 #define HYPERCALL_PAGESIZE              0x1000
  80 #define HYPERCALL_SHINFO_PAGESIZE       0x1000
  81 
  82         .data
  83         .align  HYPERCALL_SHINFO_PAGESIZE
  84         .globl  hypercall_shared_info_page
  85         .type   hypercall_shared_info_page, @object
  86         .size   hypercall_shared_info_page, HYPERCALL_SHINFO_PAGESIZE
  87 hypercall_shared_info_page:
  88         .skip   HYPERCALL_SHINFO_PAGESIZE
  89 
  90         .text
  91         .align  HYPERCALL_PAGESIZE
  92         .globl  hypercall_page
  93         .type   hypercall_page, @function
  94 hypercall_page:
  95         .skip   HYPERCALL_PAGESIZE
  96         .size   hypercall_page, HYPERCALL_PAGESIZE
  97 #define TRAP_INSTR                      \
  98         shll    $5, %eax;               \
  99         addq    $hypercall_page, %rax;  \
 100         INDIRECT_JMP_REG(rax);
 101 
 102 #else /* !_xpv */
 103 
 104 #define TRAP_INSTR      syscall
 105 #endif /* !__xpv */
 106 
 107 
 108         ENTRY_NP(__hypercall0)
 109         ALTENTRY(__hypercall0_int)
 110         movl    %edi, %eax
 111         TRAP_INSTR
 112         ret
 113         SET_SIZE(__hypercall0)
 114 
 115         ENTRY_NP(__hypercall1)
 116         ALTENTRY(__hypercall1_int)
 117         movl    %edi, %eax
 118         movq    %rsi, %rdi              /* arg 1 */
 119         TRAP_INSTR
 120         ret
 121         SET_SIZE(__hypercall1)
 122 
 123         ENTRY_NP(__hypercall2)
 124         ALTENTRY(__hypercall2_int)
 125         movl    %edi, %eax
 126         movq    %rsi, %rdi              /* arg 1 */
 127         movq    %rdx, %rsi              /* arg 2 */
 128         TRAP_INSTR
 129         ret
 130         SET_SIZE(__hypercall2)
 131 
 132         ENTRY_NP(__hypercall3)
 133         ALTENTRY(__hypercall3_int)
 134         movl    %edi, %eax
 135         movq    %rsi, %rdi              /* arg 1 */
 136         movq    %rdx, %rsi              /* arg 2 */
 137         movq    %rcx, %rdx              /* arg 3 */
 138         TRAP_INSTR
 139         ret
 140         SET_SIZE(__hypercall3)
 141 
 142         ENTRY_NP(__hypercall4)
 143         ALTENTRY(__hypercall4_int)
 144         movl    %edi, %eax
 145         movq    %rsi, %rdi              /* arg 1 */
 146         movq    %rdx, %rsi              /* arg 2 */
 147         movq    %rcx, %rdx              /* arg 3 */
 148         movq    %r8, %r10               /* r10 = 4th arg */
 149         TRAP_INSTR
 150         ret
 151         SET_SIZE(__hypercall4)
 152 
 153         ENTRY_NP(__hypercall5)
 154         ALTENTRY(__hypercall5_int)
 155         movl    %edi, %eax
 156         movq    %rsi, %rdi              /* arg 1 */
 157         movq    %rdx, %rsi              /* arg 2 */
 158         movq    %rcx, %rdx              /* arg 3 */
 159         movq    %r8, %r10               /* r10 = 4th arg */
 160         movq    %r9, %r8                /* arg 5 */
 161         TRAP_INSTR
 162         ret
 163         SET_SIZE(__hypercall5)
 164