root/arch/powerpc/kernel/kvm_emul.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  *
   4  * Copyright SUSE Linux Products GmbH 2010
   5  * Copyright 2010-2011 Freescale Semiconductor, Inc.
   6  *
   7  * Authors: Alexander Graf <agraf@suse.de>
   8  */
   9 
  10 #include <asm/ppc_asm.h>
  11 #include <asm/kvm_asm.h>
  12 #include <asm/reg.h>
  13 #include <asm/page.h>
  14 #include <asm/asm-offsets.h>
  15 #include <asm/asm-compat.h>
  16 
  17 #define KVM_MAGIC_PAGE          (-4096)
  18 
  19 #ifdef CONFIG_64BIT
  20 #define LL64(reg, offs, reg2)   ld      reg, (offs)(reg2)
  21 #define STL64(reg, offs, reg2)  std     reg, (offs)(reg2)
  22 #else
  23 #define LL64(reg, offs, reg2)   lwz     reg, (offs + 4)(reg2)
  24 #define STL64(reg, offs, reg2)  stw     reg, (offs + 4)(reg2)
  25 #endif
  26 
  27 #define SCRATCH_SAVE                                                    \
  28         /* Enable critical section. We are critical if                  \
  29            shared->critical == r1 */                                    \
  30         STL64(r1, KVM_MAGIC_PAGE + KVM_MAGIC_CRITICAL, 0);              \
  31                                                                         \
  32         /* Save state */                                                \
  33         PPC_STL r31, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH1)(0);          \
  34         PPC_STL r30, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH2)(0);          \
  35         mfcr    r31;                                                    \
  36         stw     r31, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH3)(0);
  37 
  38 #define SCRATCH_RESTORE                                                 \
  39         /* Restore state */                                             \
  40         PPC_LL  r31, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH1)(0);          \
  41         lwz     r30, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH3)(0);          \
  42         mtcr    r30;                                                    \
  43         PPC_LL  r30, (KVM_MAGIC_PAGE + KVM_MAGIC_SCRATCH2)(0);          \
  44                                                                         \
  45         /* Disable critical section. We are critical if                 \
  46            shared->critical == r1 and r2 is always != r1 */             \
  47         STL64(r2, KVM_MAGIC_PAGE + KVM_MAGIC_CRITICAL, 0);
  48 
  49 .global kvm_template_start
  50 kvm_template_start:
  51 
  52 .global kvm_emulate_mtmsrd
  53 kvm_emulate_mtmsrd:
  54 
  55         SCRATCH_SAVE
  56 
  57         /* Put MSR & ~(MSR_EE|MSR_RI) in r31 */
  58         LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
  59         lis     r30, (~(MSR_EE | MSR_RI))@h
  60         ori     r30, r30, (~(MSR_EE | MSR_RI))@l
  61         and     r31, r31, r30
  62 
  63         /* OR the register's (MSR_EE|MSR_RI) on MSR */
  64 kvm_emulate_mtmsrd_reg:
  65         ori     r30, r0, 0
  66         andi.   r30, r30, (MSR_EE|MSR_RI)
  67         or      r31, r31, r30
  68 
  69         /* Put MSR back into magic page */
  70         STL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
  71 
  72         /* Check if we have to fetch an interrupt */
  73         lwz     r31, (KVM_MAGIC_PAGE + KVM_MAGIC_INT)(0)
  74         cmpwi   r31, 0
  75         beq+    no_check
  76 
  77         /* Check if we may trigger an interrupt */
  78         andi.   r30, r30, MSR_EE
  79         beq     no_check
  80 
  81         SCRATCH_RESTORE
  82 
  83         /* Nag hypervisor */
  84 kvm_emulate_mtmsrd_orig_ins:
  85         tlbsync
  86 
  87         b       kvm_emulate_mtmsrd_branch
  88 
  89 no_check:
  90 
  91         SCRATCH_RESTORE
  92 
  93         /* Go back to caller */
  94 kvm_emulate_mtmsrd_branch:
  95         b       .
  96 kvm_emulate_mtmsrd_end:
  97 
  98 .global kvm_emulate_mtmsrd_branch_offs
  99 kvm_emulate_mtmsrd_branch_offs:
 100         .long (kvm_emulate_mtmsrd_branch - kvm_emulate_mtmsrd) / 4
 101 
 102 .global kvm_emulate_mtmsrd_reg_offs
 103 kvm_emulate_mtmsrd_reg_offs:
 104         .long (kvm_emulate_mtmsrd_reg - kvm_emulate_mtmsrd) / 4
 105 
 106 .global kvm_emulate_mtmsrd_orig_ins_offs
 107 kvm_emulate_mtmsrd_orig_ins_offs:
 108         .long (kvm_emulate_mtmsrd_orig_ins - kvm_emulate_mtmsrd) / 4
 109 
 110 .global kvm_emulate_mtmsrd_len
 111 kvm_emulate_mtmsrd_len:
 112         .long (kvm_emulate_mtmsrd_end - kvm_emulate_mtmsrd) / 4
 113 
 114 
 115 #define MSR_SAFE_BITS (MSR_EE | MSR_RI)
 116 #define MSR_CRITICAL_BITS ~MSR_SAFE_BITS
 117 
 118 .global kvm_emulate_mtmsr
 119 kvm_emulate_mtmsr:
 120 
 121         SCRATCH_SAVE
 122 
 123         /* Fetch old MSR in r31 */
 124         LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
 125 
 126         /* Find the changed bits between old and new MSR */
 127 kvm_emulate_mtmsr_reg1:
 128         ori     r30, r0, 0
 129         xor     r31, r30, r31
 130 
 131         /* Check if we need to really do mtmsr */
 132         LOAD_REG_IMMEDIATE(r30, MSR_CRITICAL_BITS)
 133         and.    r31, r31, r30
 134 
 135         /* No critical bits changed? Maybe we can stay in the guest. */
 136         beq     maybe_stay_in_guest
 137 
 138 do_mtmsr:
 139 
 140         SCRATCH_RESTORE
 141 
 142         /* Just fire off the mtmsr if it's critical */
 143 kvm_emulate_mtmsr_orig_ins:
 144         mtmsr   r0
 145 
 146         b       kvm_emulate_mtmsr_branch
 147 
 148 maybe_stay_in_guest:
 149 
 150         /* Get the target register in r30 */
 151 kvm_emulate_mtmsr_reg2:
 152         ori     r30, r0, 0
 153 
 154         /* Put MSR into magic page because we don't call mtmsr */
 155         STL64(r30, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
 156 
 157         /* Check if we have to fetch an interrupt */
 158         lwz     r31, (KVM_MAGIC_PAGE + KVM_MAGIC_INT)(0)
 159         cmpwi   r31, 0
 160         beq+    no_mtmsr
 161 
 162         /* Check if we may trigger an interrupt */
 163         andi.   r31, r30, MSR_EE
 164         bne     do_mtmsr
 165 
 166 no_mtmsr:
 167 
 168         SCRATCH_RESTORE
 169 
 170         /* Go back to caller */
 171 kvm_emulate_mtmsr_branch:
 172         b       .
 173 kvm_emulate_mtmsr_end:
 174 
 175 .global kvm_emulate_mtmsr_branch_offs
 176 kvm_emulate_mtmsr_branch_offs:
 177         .long (kvm_emulate_mtmsr_branch - kvm_emulate_mtmsr) / 4
 178 
 179 .global kvm_emulate_mtmsr_reg1_offs
 180 kvm_emulate_mtmsr_reg1_offs:
 181         .long (kvm_emulate_mtmsr_reg1 - kvm_emulate_mtmsr) / 4
 182 
 183 .global kvm_emulate_mtmsr_reg2_offs
 184 kvm_emulate_mtmsr_reg2_offs:
 185         .long (kvm_emulate_mtmsr_reg2 - kvm_emulate_mtmsr) / 4
 186 
 187 .global kvm_emulate_mtmsr_orig_ins_offs
 188 kvm_emulate_mtmsr_orig_ins_offs:
 189         .long (kvm_emulate_mtmsr_orig_ins - kvm_emulate_mtmsr) / 4
 190 
 191 .global kvm_emulate_mtmsr_len
 192 kvm_emulate_mtmsr_len:
 193         .long (kvm_emulate_mtmsr_end - kvm_emulate_mtmsr) / 4
 194 
 195 #ifdef CONFIG_BOOKE
 196 
 197 /* also used for wrteei 1 */
 198 .global kvm_emulate_wrtee
 199 kvm_emulate_wrtee:
 200 
 201         SCRATCH_SAVE
 202 
 203         /* Fetch old MSR in r31 */
 204         LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
 205 
 206         /* Insert new MSR[EE] */
 207 kvm_emulate_wrtee_reg:
 208         ori     r30, r0, 0
 209         rlwimi  r31, r30, 0, MSR_EE
 210 
 211         /*
 212          * If MSR[EE] is now set, check for a pending interrupt.
 213          * We could skip this if MSR[EE] was already on, but that
 214          * should be rare, so don't bother.
 215          */
 216         andi.   r30, r30, MSR_EE
 217 
 218         /* Put MSR into magic page because we don't call wrtee */
 219         STL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
 220 
 221         beq     no_wrtee
 222 
 223         /* Check if we have to fetch an interrupt */
 224         lwz     r30, (KVM_MAGIC_PAGE + KVM_MAGIC_INT)(0)
 225         cmpwi   r30, 0
 226         bne     do_wrtee
 227 
 228 no_wrtee:
 229         SCRATCH_RESTORE
 230 
 231         /* Go back to caller */
 232 kvm_emulate_wrtee_branch:
 233         b       .
 234 
 235 do_wrtee:
 236         SCRATCH_RESTORE
 237 
 238         /* Just fire off the wrtee if it's critical */
 239 kvm_emulate_wrtee_orig_ins:
 240         wrtee   r0
 241 
 242         b       kvm_emulate_wrtee_branch
 243 
 244 kvm_emulate_wrtee_end:
 245 
 246 .global kvm_emulate_wrtee_branch_offs
 247 kvm_emulate_wrtee_branch_offs:
 248         .long (kvm_emulate_wrtee_branch - kvm_emulate_wrtee) / 4
 249 
 250 .global kvm_emulate_wrtee_reg_offs
 251 kvm_emulate_wrtee_reg_offs:
 252         .long (kvm_emulate_wrtee_reg - kvm_emulate_wrtee) / 4
 253 
 254 .global kvm_emulate_wrtee_orig_ins_offs
 255 kvm_emulate_wrtee_orig_ins_offs:
 256         .long (kvm_emulate_wrtee_orig_ins - kvm_emulate_wrtee) / 4
 257 
 258 .global kvm_emulate_wrtee_len
 259 kvm_emulate_wrtee_len:
 260         .long (kvm_emulate_wrtee_end - kvm_emulate_wrtee) / 4
 261 
 262 .global kvm_emulate_wrteei_0
 263 kvm_emulate_wrteei_0:
 264         SCRATCH_SAVE
 265 
 266         /* Fetch old MSR in r31 */
 267         LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
 268 
 269         /* Remove MSR_EE from old MSR */
 270         rlwinm  r31, r31, 0, ~MSR_EE
 271 
 272         /* Write new MSR value back */
 273         STL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
 274 
 275         SCRATCH_RESTORE
 276 
 277         /* Go back to caller */
 278 kvm_emulate_wrteei_0_branch:
 279         b       .
 280 kvm_emulate_wrteei_0_end:
 281 
 282 .global kvm_emulate_wrteei_0_branch_offs
 283 kvm_emulate_wrteei_0_branch_offs:
 284         .long (kvm_emulate_wrteei_0_branch - kvm_emulate_wrteei_0) / 4
 285 
 286 .global kvm_emulate_wrteei_0_len
 287 kvm_emulate_wrteei_0_len:
 288         .long (kvm_emulate_wrteei_0_end - kvm_emulate_wrteei_0) / 4
 289 
 290 #endif /* CONFIG_BOOKE */
 291 
 292 #ifdef CONFIG_PPC_BOOK3S_32
 293 
 294 .global kvm_emulate_mtsrin
 295 kvm_emulate_mtsrin:
 296 
 297         SCRATCH_SAVE
 298 
 299         LL64(r31, KVM_MAGIC_PAGE + KVM_MAGIC_MSR, 0)
 300         andi.   r31, r31, MSR_DR | MSR_IR
 301         beq     kvm_emulate_mtsrin_reg1
 302 
 303         SCRATCH_RESTORE
 304 
 305 kvm_emulate_mtsrin_orig_ins:
 306         nop
 307         b       kvm_emulate_mtsrin_branch
 308 
 309 kvm_emulate_mtsrin_reg1:
 310         /* rX >> 26 */
 311         rlwinm  r30,r0,6,26,29
 312 
 313 kvm_emulate_mtsrin_reg2:
 314         stw     r0, (KVM_MAGIC_PAGE + KVM_MAGIC_SR)(r30)
 315 
 316         SCRATCH_RESTORE
 317 
 318         /* Go back to caller */
 319 kvm_emulate_mtsrin_branch:
 320         b       .
 321 kvm_emulate_mtsrin_end:
 322 
 323 .global kvm_emulate_mtsrin_branch_offs
 324 kvm_emulate_mtsrin_branch_offs:
 325         .long (kvm_emulate_mtsrin_branch - kvm_emulate_mtsrin) / 4
 326 
 327 .global kvm_emulate_mtsrin_reg1_offs
 328 kvm_emulate_mtsrin_reg1_offs:
 329         .long (kvm_emulate_mtsrin_reg1 - kvm_emulate_mtsrin) / 4
 330 
 331 .global kvm_emulate_mtsrin_reg2_offs
 332 kvm_emulate_mtsrin_reg2_offs:
 333         .long (kvm_emulate_mtsrin_reg2 - kvm_emulate_mtsrin) / 4
 334 
 335 .global kvm_emulate_mtsrin_orig_ins_offs
 336 kvm_emulate_mtsrin_orig_ins_offs:
 337         .long (kvm_emulate_mtsrin_orig_ins - kvm_emulate_mtsrin) / 4
 338 
 339 .global kvm_emulate_mtsrin_len
 340 kvm_emulate_mtsrin_len:
 341         .long (kvm_emulate_mtsrin_end - kvm_emulate_mtsrin) / 4
 342 
 343 #endif /* CONFIG_PPC_BOOK3S_32 */
 344 
 345         .balign 4
 346         .global kvm_tmp
 347 kvm_tmp:
 348         .space  (64 * 1024)
 349 
 350 .global kvm_tmp_end
 351 kvm_tmp_end:
 352 
 353 .global kvm_template_end
 354 kvm_template_end:

/* [<][>][^][v][top][bottom][index][help] */