linux/arch/powerpc/kvm/book3s_hv_interrupts.S
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 *
   4 * Copyright 2011 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
   5 *
   6 * Derived from book3s_interrupts.S, which is:
   7 * Copyright SUSE Linux Products GmbH 2009
   8 *
   9 * Authors: Alexander Graf <agraf@suse.de>
  10 */
  11
  12#include <asm/ppc_asm.h>
  13#include <asm/kvm_asm.h>
  14#include <asm/reg.h>
  15#include <asm/page.h>
  16#include <asm/asm-offsets.h>
  17#include <asm/exception-64s.h>
  18#include <asm/ppc-opcode.h>
  19#include <asm/asm-compat.h>
  20#include <asm/feature-fixups.h>
  21
  22/*****************************************************************************
  23 *                                                                           *
  24 *     Guest entry / exit code that is in kernel module memory (vmalloc)     *
  25 *                                                                           *
  26 ****************************************************************************/
  27
  28/* Registers:
  29 *  none
  30 */
  31_GLOBAL(__kvmppc_vcore_entry)
  32
  33        /* Write correct stack frame */
  34        mflr    r0
  35        std     r0,PPC_LR_STKOFF(r1)
  36
  37        /* Save host state to the stack */
  38        stdu    r1, -SWITCH_FRAME_SIZE(r1)
  39
  40        /* Save non-volatile registers (r14 - r31) and CR */
  41        SAVE_NVGPRS(r1)
  42        mfcr    r3
  43        std     r3, _CCR(r1)
  44
  45        /* Save host DSCR */
  46        mfspr   r3, SPRN_DSCR
  47        std     r3, HSTATE_DSCR(r13)
  48
  49BEGIN_FTR_SECTION
  50        /* Save host DABR */
  51        mfspr   r3, SPRN_DABR
  52        std     r3, HSTATE_DABR(r13)
  53END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
  54
  55        /* Save host PMU registers */
  56        bl      kvmhv_save_host_pmu
  57
  58        /*
  59         * Put whatever is in the decrementer into the
  60         * hypervisor decrementer.
  61         */
  62BEGIN_FTR_SECTION
  63        ld      r5, HSTATE_KVM_VCORE(r13)
  64        ld      r6, VCORE_KVM(r5)
  65        ld      r9, KVM_HOST_LPCR(r6)
  66        andis.  r9, r9, LPCR_LD@h
  67END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
  68        mfspr   r8,SPRN_DEC
  69        mftb    r7
  70BEGIN_FTR_SECTION
  71        /* On POWER9, don't sign-extend if host LPCR[LD] bit is set */
  72        bne     32f
  73END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
  74        extsw   r8,r8
  7532:     mtspr   SPRN_HDEC,r8
  76        add     r8,r8,r7
  77        std     r8,HSTATE_DECEXP(r13)
  78
  79        /* Jump to partition switch code */
  80        bl      kvmppc_hv_entry_trampoline
  81        nop
  82
  83/*
  84 * We return here in virtual mode after the guest exits
  85 * with something that we can't handle in real mode.
  86 * Interrupts are still hard-disabled.
  87 */
  88
  89        /*
  90         * Register usage at this point:
  91         *
  92         * R1       = host R1
  93         * R2       = host R2
  94         * R3       = trap number on this thread
  95         * R12      = exit handler id
  96         * R13      = PACA
  97         */
  98
  99        /* Restore non-volatile host registers (r14 - r31) and CR */
 100        REST_NVGPRS(r1)
 101        ld      r4, _CCR(r1)
 102        mtcr    r4
 103
 104        addi    r1, r1, SWITCH_FRAME_SIZE
 105        ld      r0, PPC_LR_STKOFF(r1)
 106        mtlr    r0
 107        blr
 108
 109_GLOBAL(kvmhv_save_host_pmu)
 110BEGIN_FTR_SECTION
 111        /* Work around P8 PMAE bug */
 112        li      r3, -1
 113        clrrdi  r3, r3, 10
 114        mfspr   r8, SPRN_MMCR2
 115        mtspr   SPRN_MMCR2, r3          /* freeze all counters using MMCR2 */
 116        isync
 117END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 118        li      r3, 1
 119        sldi    r3, r3, 31              /* MMCR0_FC (freeze counters) bit */
 120        mfspr   r7, SPRN_MMCR0          /* save MMCR0 */
 121        mtspr   SPRN_MMCR0, r3          /* freeze all counters, disable interrupts */
 122        mfspr   r6, SPRN_MMCRA
 123        /* Clear MMCRA in order to disable SDAR updates */
 124        li      r5, 0
 125        mtspr   SPRN_MMCRA, r5
 126        isync
 127        lbz     r5, PACA_PMCINUSE(r13)  /* is the host using the PMU? */
 128        cmpwi   r5, 0
 129        beq     31f                     /* skip if not */
 130        mfspr   r5, SPRN_MMCR1
 131        mfspr   r9, SPRN_SIAR
 132        mfspr   r10, SPRN_SDAR
 133        std     r7, HSTATE_MMCR0(r13)
 134        std     r5, HSTATE_MMCR1(r13)
 135        std     r6, HSTATE_MMCRA(r13)
 136        std     r9, HSTATE_SIAR(r13)
 137        std     r10, HSTATE_SDAR(r13)
 138BEGIN_FTR_SECTION
 139        mfspr   r9, SPRN_SIER
 140        std     r8, HSTATE_MMCR2(r13)
 141        std     r9, HSTATE_SIER(r13)
 142END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 143BEGIN_FTR_SECTION
 144        mfspr   r5, SPRN_MMCR3
 145        mfspr   r6, SPRN_SIER2
 146        mfspr   r7, SPRN_SIER3
 147        std     r5, HSTATE_MMCR3(r13)
 148        std     r6, HSTATE_SIER2(r13)
 149        std     r7, HSTATE_SIER3(r13)
 150END_FTR_SECTION_IFSET(CPU_FTR_ARCH_31)
 151        mfspr   r3, SPRN_PMC1
 152        mfspr   r5, SPRN_PMC2
 153        mfspr   r6, SPRN_PMC3
 154        mfspr   r7, SPRN_PMC4
 155        mfspr   r8, SPRN_PMC5
 156        mfspr   r9, SPRN_PMC6
 157        stw     r3, HSTATE_PMC1(r13)
 158        stw     r5, HSTATE_PMC2(r13)
 159        stw     r6, HSTATE_PMC3(r13)
 160        stw     r7, HSTATE_PMC4(r13)
 161        stw     r8, HSTATE_PMC5(r13)
 162        stw     r9, HSTATE_PMC6(r13)
 16331:     blr
 164