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

book3s_rmhandlers.S (4186B)


      1/* SPDX-License-Identifier: GPL-2.0-only */
      2/*
      3 *
      4 * Copyright SUSE Linux Products GmbH 2009
      5 *
      6 * Authors: Alexander Graf <agraf@suse.de>
      7 */
      8
      9#include <asm/ppc_asm.h>
     10#include <asm/kvm_asm.h>
     11#include <asm/reg.h>
     12#include <asm/mmu.h>
     13#include <asm/page.h>
     14#include <asm/asm-offsets.h>
     15#include <asm/asm-compat.h>
     16
     17#ifdef CONFIG_PPC_BOOK3S_64
     18#include <asm/exception-64s.h>
     19#endif
     20
     21/*****************************************************************************
     22 *                                                                           *
     23 *        Real Mode handlers that need to be in low physical memory          *
     24 *                                                                           *
     25 ****************************************************************************/
     26
     27#if defined(CONFIG_PPC_BOOK3S_64)
     28
     29#ifdef CONFIG_PPC64_ELF_ABI_V2
     30#define FUNC(name) 		name
     31#else
     32#define FUNC(name) 		GLUE(.,name)
     33#endif
     34
     35#elif defined(CONFIG_PPC_BOOK3S_32)
     36
     37#define FUNC(name)		name
     38
     39#define RFI_TO_KERNEL	rfi
     40#define RFI_TO_GUEST	rfi
     41
     42.macro INTERRUPT_TRAMPOLINE intno
     43
     44.global kvmppc_trampoline_\intno
     45kvmppc_trampoline_\intno:
     46
     47	mtspr	SPRN_SPRG_SCRATCH0, r13		/* Save r13 */
     48
     49	/*
     50	 * First thing to do is to find out if we're coming
     51	 * from a KVM guest or a Linux process.
     52	 *
     53	 * To distinguish, we check a magic byte in the PACA/current
     54	 */
     55	mfspr	r13, SPRN_SPRG_THREAD
     56	lwz	r13, THREAD_KVM_SVCPU(r13)
     57	/* PPC32 can have a NULL pointer - let's check for that */
     58	mtspr   SPRN_SPRG_SCRATCH1, r12		/* Save r12 */
     59	mfcr	r12
     60	cmpwi	r13, 0
     61	bne	1f
     622:	mtcr	r12
     63	mfspr	r12, SPRN_SPRG_SCRATCH1
     64	mfspr	r13, SPRN_SPRG_SCRATCH0		/* r13 = original r13 */
     65	b	kvmppc_resume_\intno		/* Get back original handler */
     66
     671:	tophys(r13, r13)
     68	stw	r12, HSTATE_SCRATCH1(r13)
     69	mfspr	r12, SPRN_SPRG_SCRATCH1
     70	stw	r12, HSTATE_SCRATCH0(r13)
     71	lbz	r12, HSTATE_IN_GUEST(r13)
     72	cmpwi	r12, KVM_GUEST_MODE_NONE
     73	bne	..kvmppc_handler_hasmagic_\intno
     74	/* No KVM guest? Then jump back to the Linux handler! */
     75	lwz	r12, HSTATE_SCRATCH1(r13)
     76	b	2b
     77
     78	/* Now we know we're handling a KVM guest */
     79..kvmppc_handler_hasmagic_\intno:
     80
     81	/* Should we just skip the faulting instruction? */
     82	cmpwi	r12, KVM_GUEST_MODE_SKIP
     83	beq	kvmppc_handler_skip_ins
     84
     85	/* Let's store which interrupt we're handling */
     86	li	r12, \intno
     87
     88	/* Jump into the SLB exit code that goes to the highmem handler */
     89	b	kvmppc_handler_trampoline_exit
     90
     91.endm
     92
     93INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_SYSTEM_RESET
     94INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_MACHINE_CHECK
     95INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_DATA_STORAGE
     96INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_INST_STORAGE
     97INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_EXTERNAL
     98INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_ALIGNMENT
     99INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_PROGRAM
    100INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_FP_UNAVAIL
    101INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_DECREMENTER
    102INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_SYSCALL
    103INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_TRACE
    104INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_PERFMON
    105INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_ALTIVEC
    106
    107/*
    108 * Bring us back to the faulting code, but skip the
    109 * faulting instruction.
    110 *
    111 * This is a generic exit path from the interrupt
    112 * trampolines above.
    113 *
    114 * Input Registers:
    115 *
    116 * R12            = free
    117 * R13            = Shadow VCPU (PACA)
    118 * HSTATE.SCRATCH0 = guest R12
    119 * HSTATE.SCRATCH1 = guest CR
    120 * SPRG_SCRATCH0  = guest R13
    121 *
    122 */
    123kvmppc_handler_skip_ins:
    124
    125	/* Patch the IP to the next instruction */
    126	mfsrr0	r12
    127	addi	r12, r12, 4
    128	mtsrr0	r12
    129
    130	/* Clean up all state */
    131	lwz	r12, HSTATE_SCRATCH1(r13)
    132	mtcr	r12
    133	PPC_LL	r12, HSTATE_SCRATCH0(r13)
    134	GET_SCRATCH0(r13)
    135
    136	/* And get back into the code */
    137	RFI_TO_KERNEL
    138#endif
    139
    140/*
    141 * Call kvmppc_handler_trampoline_enter in real mode
    142 *
    143 * On entry, r4 contains the guest shadow MSR
    144 * MSR.EE has to be 0 when calling this function
    145 */
    146_GLOBAL_TOC(kvmppc_entry_trampoline)
    147	mfmsr	r5
    148	LOAD_REG_ADDR(r7, kvmppc_handler_trampoline_enter)
    149	toreal(r7)
    150
    151	li	r6, MSR_IR | MSR_DR
    152	andc	r6, r5, r6	/* Clear DR and IR in MSR value */
    153	/*
    154	 * Set EE in HOST_MSR so that it's enabled when we get into our
    155	 * C exit handler function.
    156	 */
    157	ori	r5, r5, MSR_EE
    158	mtsrr0	r7
    159	mtsrr1	r6
    160	RFI_TO_KERNEL
    161
    162#include "book3s_segment.S"