Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  *
0004  * Copyright 2011 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
0005  *
0006  * Derived from book3s_interrupts.S, which is:
0007  * Copyright SUSE Linux Products GmbH 2009
0008  *
0009  * Authors: Alexander Graf <agraf@suse.de>
0010  */
0011 
0012 #include <asm/ppc_asm.h>
0013 #include <asm/kvm_asm.h>
0014 #include <asm/reg.h>
0015 #include <asm/page.h>
0016 #include <asm/asm-offsets.h>
0017 #include <asm/exception-64s.h>
0018 #include <asm/ppc-opcode.h>
0019 #include <asm/asm-compat.h>
0020 #include <asm/feature-fixups.h>
0021 
0022 /*****************************************************************************
0023  *                                                                           *
0024  *     Guest entry / exit code that is in kernel module memory (vmalloc)     *
0025  *                                                                           *
0026  ****************************************************************************/
0027 
0028 /* Registers:
0029  *  none
0030  */
0031 _GLOBAL(__kvmppc_vcore_entry)
0032 
0033     /* Write correct stack frame */
0034     mflr    r0
0035     std r0,PPC_LR_STKOFF(r1)
0036 
0037     /* Save host state to the stack */
0038     stdu    r1, -SWITCH_FRAME_SIZE(r1)
0039 
0040     /* Save non-volatile registers (r14 - r31) and CR */
0041     SAVE_NVGPRS(r1)
0042     mfcr    r3
0043     std r3, _CCR(r1)
0044 
0045     /* Save host DSCR */
0046     mfspr   r3, SPRN_DSCR
0047     std r3, HSTATE_DSCR(r13)
0048 
0049 BEGIN_FTR_SECTION
0050     /* Save host DABR */
0051     mfspr   r3, SPRN_DABR
0052     std r3, HSTATE_DABR(r13)
0053 END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
0054 
0055     /* Save host PMU registers */
0056     bl  kvmhv_save_host_pmu
0057 
0058     /*
0059      * Put whatever is in the decrementer into the
0060      * hypervisor decrementer.
0061      * Because of a hardware deviation in P8,
0062      * we need to set LPCR[HDICE] before writing HDEC.
0063      */
0064     ld  r5, HSTATE_KVM_VCORE(r13)
0065     ld  r6, VCORE_KVM(r5)
0066     ld  r9, KVM_HOST_LPCR(r6)
0067     ori r8, r9, LPCR_HDICE
0068     mtspr   SPRN_LPCR, r8
0069     isync
0070     mfspr   r8,SPRN_DEC
0071     mftb    r7
0072     extsw   r8,r8
0073     mtspr   SPRN_HDEC,r8
0074     add r8,r8,r7
0075     std r8,HSTATE_DECEXP(r13)
0076 
0077     /* Jump to partition switch code */
0078     bl  kvmppc_hv_entry_trampoline
0079     nop
0080 
0081 /*
0082  * We return here in virtual mode after the guest exits
0083  * with something that we can't handle in real mode.
0084  * Interrupts are still hard-disabled.
0085  */
0086 
0087     /*
0088      * Register usage at this point:
0089      *
0090      * R1       = host R1
0091      * R2       = host R2
0092      * R3       = trap number on this thread
0093      * R12      = exit handler id
0094      * R13      = PACA
0095      */
0096 
0097     /* Restore non-volatile host registers (r14 - r31) and CR */
0098     REST_NVGPRS(r1)
0099     ld  r4, _CCR(r1)
0100     mtcr    r4
0101 
0102     addi    r1, r1, SWITCH_FRAME_SIZE
0103     ld  r0, PPC_LR_STKOFF(r1)
0104     mtlr    r0
0105     blr
0106 
0107 /*
0108  * void kvmhv_save_host_pmu(void)
0109  */
0110 kvmhv_save_host_pmu:
0111 BEGIN_FTR_SECTION
0112     /* Work around P8 PMAE bug */
0113     li  r3, -1
0114     clrrdi  r3, r3, 10
0115     mfspr   r8, SPRN_MMCR2
0116     mtspr   SPRN_MMCR2, r3      /* freeze all counters using MMCR2 */
0117     isync
0118 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
0119     li  r3, 1
0120     sldi    r3, r3, 31      /* MMCR0_FC (freeze counters) bit */
0121     mfspr   r7, SPRN_MMCR0      /* save MMCR0 */
0122     mtspr   SPRN_MMCR0, r3      /* freeze all counters, disable interrupts */
0123     mfspr   r6, SPRN_MMCRA
0124     /* Clear MMCRA in order to disable SDAR updates */
0125     li  r5, 0
0126     mtspr   SPRN_MMCRA, r5
0127     isync
0128     lbz r5, PACA_PMCINUSE(r13)  /* is the host using the PMU? */
0129     cmpwi   r5, 0
0130     beq 31f         /* skip if not */
0131     mfspr   r5, SPRN_MMCR1
0132     mfspr   r9, SPRN_SIAR
0133     mfspr   r10, SPRN_SDAR
0134     std r7, HSTATE_MMCR0(r13)
0135     std r5, HSTATE_MMCR1(r13)
0136     std r6, HSTATE_MMCRA(r13)
0137     std r9, HSTATE_SIAR(r13)
0138     std r10, HSTATE_SDAR(r13)
0139 BEGIN_FTR_SECTION
0140     mfspr   r9, SPRN_SIER
0141     std r8, HSTATE_MMCR2(r13)
0142     std r9, HSTATE_SIER(r13)
0143 END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
0144     mfspr   r3, SPRN_PMC1
0145     mfspr   r5, SPRN_PMC2
0146     mfspr   r6, SPRN_PMC3
0147     mfspr   r7, SPRN_PMC4
0148     mfspr   r8, SPRN_PMC5
0149     mfspr   r9, SPRN_PMC6
0150     stw r3, HSTATE_PMC1(r13)
0151     stw r5, HSTATE_PMC2(r13)
0152     stw r6, HSTATE_PMC3(r13)
0153     stw r7, HSTATE_PMC4(r13)
0154     stw r8, HSTATE_PMC5(r13)
0155     stw r9, HSTATE_PMC6(r13)
0156 31: blr