cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

kvm_emul.S (8167B)


      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
     50kvm_template_start:
     51
     52.global kvm_emulate_mtmsrd
     53kvm_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 */
     64kvm_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 */
     84kvm_emulate_mtmsrd_orig_ins:
     85	tlbsync
     86
     87	b	kvm_emulate_mtmsrd_branch
     88
     89no_check:
     90
     91	SCRATCH_RESTORE
     92
     93	/* Go back to caller */
     94kvm_emulate_mtmsrd_branch:
     95	b	.
     96kvm_emulate_mtmsrd_end:
     97
     98.global kvm_emulate_mtmsrd_branch_offs
     99kvm_emulate_mtmsrd_branch_offs:
    100	.long (kvm_emulate_mtmsrd_branch - kvm_emulate_mtmsrd) / 4
    101
    102.global kvm_emulate_mtmsrd_reg_offs
    103kvm_emulate_mtmsrd_reg_offs:
    104	.long (kvm_emulate_mtmsrd_reg - kvm_emulate_mtmsrd) / 4
    105
    106.global kvm_emulate_mtmsrd_orig_ins_offs
    107kvm_emulate_mtmsrd_orig_ins_offs:
    108	.long (kvm_emulate_mtmsrd_orig_ins - kvm_emulate_mtmsrd) / 4
    109
    110.global kvm_emulate_mtmsrd_len
    111kvm_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
    119kvm_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 */
    127kvm_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
    138do_mtmsr:
    139
    140	SCRATCH_RESTORE
    141
    142	/* Just fire off the mtmsr if it's critical */
    143kvm_emulate_mtmsr_orig_ins:
    144	mtmsr	r0
    145
    146	b	kvm_emulate_mtmsr_branch
    147
    148maybe_stay_in_guest:
    149
    150	/* Get the target register in r30 */
    151kvm_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
    166no_mtmsr:
    167
    168	SCRATCH_RESTORE
    169
    170	/* Go back to caller */
    171kvm_emulate_mtmsr_branch:
    172	b	.
    173kvm_emulate_mtmsr_end:
    174
    175.global kvm_emulate_mtmsr_branch_offs
    176kvm_emulate_mtmsr_branch_offs:
    177	.long (kvm_emulate_mtmsr_branch - kvm_emulate_mtmsr) / 4
    178
    179.global kvm_emulate_mtmsr_reg1_offs
    180kvm_emulate_mtmsr_reg1_offs:
    181	.long (kvm_emulate_mtmsr_reg1 - kvm_emulate_mtmsr) / 4
    182
    183.global kvm_emulate_mtmsr_reg2_offs
    184kvm_emulate_mtmsr_reg2_offs:
    185	.long (kvm_emulate_mtmsr_reg2 - kvm_emulate_mtmsr) / 4
    186
    187.global kvm_emulate_mtmsr_orig_ins_offs
    188kvm_emulate_mtmsr_orig_ins_offs:
    189	.long (kvm_emulate_mtmsr_orig_ins - kvm_emulate_mtmsr) / 4
    190
    191.global kvm_emulate_mtmsr_len
    192kvm_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
    199kvm_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] */
    207kvm_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
    228no_wrtee:
    229	SCRATCH_RESTORE
    230
    231	/* Go back to caller */
    232kvm_emulate_wrtee_branch:
    233	b	.
    234
    235do_wrtee:
    236	SCRATCH_RESTORE
    237
    238	/* Just fire off the wrtee if it's critical */
    239kvm_emulate_wrtee_orig_ins:
    240	wrtee	r0
    241
    242	b	kvm_emulate_wrtee_branch
    243
    244kvm_emulate_wrtee_end:
    245
    246.global kvm_emulate_wrtee_branch_offs
    247kvm_emulate_wrtee_branch_offs:
    248	.long (kvm_emulate_wrtee_branch - kvm_emulate_wrtee) / 4
    249
    250.global kvm_emulate_wrtee_reg_offs
    251kvm_emulate_wrtee_reg_offs:
    252	.long (kvm_emulate_wrtee_reg - kvm_emulate_wrtee) / 4
    253
    254.global kvm_emulate_wrtee_orig_ins_offs
    255kvm_emulate_wrtee_orig_ins_offs:
    256	.long (kvm_emulate_wrtee_orig_ins - kvm_emulate_wrtee) / 4
    257
    258.global kvm_emulate_wrtee_len
    259kvm_emulate_wrtee_len:
    260	.long (kvm_emulate_wrtee_end - kvm_emulate_wrtee) / 4
    261
    262.global kvm_emulate_wrteei_0
    263kvm_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 */
    278kvm_emulate_wrteei_0_branch:
    279	b	.
    280kvm_emulate_wrteei_0_end:
    281
    282.global kvm_emulate_wrteei_0_branch_offs
    283kvm_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
    287kvm_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
    295kvm_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
    305kvm_emulate_mtsrin_orig_ins:
    306	nop
    307	b	kvm_emulate_mtsrin_branch
    308
    309kvm_emulate_mtsrin_reg1:
    310	/* rX >> 26 */
    311	rlwinm  r30,r0,6,26,29
    312
    313kvm_emulate_mtsrin_reg2:
    314	stw	r0, (KVM_MAGIC_PAGE + KVM_MAGIC_SR)(r30)
    315
    316	SCRATCH_RESTORE
    317
    318	/* Go back to caller */
    319kvm_emulate_mtsrin_branch:
    320	b	.
    321kvm_emulate_mtsrin_end:
    322
    323.global kvm_emulate_mtsrin_branch_offs
    324kvm_emulate_mtsrin_branch_offs:
    325	.long (kvm_emulate_mtsrin_branch - kvm_emulate_mtsrin) / 4
    326
    327.global kvm_emulate_mtsrin_reg1_offs
    328kvm_emulate_mtsrin_reg1_offs:
    329	.long (kvm_emulate_mtsrin_reg1 - kvm_emulate_mtsrin) / 4
    330
    331.global kvm_emulate_mtsrin_reg2_offs
    332kvm_emulate_mtsrin_reg2_offs:
    333	.long (kvm_emulate_mtsrin_reg2 - kvm_emulate_mtsrin) / 4
    334
    335.global kvm_emulate_mtsrin_orig_ins_offs
    336kvm_emulate_mtsrin_orig_ins_offs:
    337	.long (kvm_emulate_mtsrin_orig_ins - kvm_emulate_mtsrin) / 4
    338
    339.global kvm_emulate_mtsrin_len
    340kvm_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
    347kvm_tmp:
    348	.space	(64 * 1024)
    349
    350.global kvm_tmp_end
    351kvm_tmp_end:
    352
    353.global kvm_template_end
    354kvm_template_end: