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         * Because of a hardware deviation in P8,
  62         * we need to set LPCR[HDICE] before writing HDEC.
  63         */
  64        ld      r5, HSTATE_KVM_VCORE(r13)
  65        ld      r6, VCORE_KVM(r5)
  66        ld      r9, KVM_HOST_LPCR(r6)
  67        ori     r8, r9, LPCR_HDICE
  68        mtspr   SPRN_LPCR, r8
  69        isync
  70        mfspr   r8,SPRN_DEC
  71        mftb    r7
  72        extsw   r8,r8
  73        mtspr   SPRN_HDEC,r8
  74        add     r8,r8,r7
  75        std     r8,HSTATE_DECEXP(r13)
  76
  77        /* Jump to partition switch code */
  78        bl      kvmppc_hv_entry_trampoline
  79        nop
  80
  81/*
  82 * We return here in virtual mode after the guest exits
  83 * with something that we can't handle in real mode.
  84 * Interrupts are still hard-disabled.
  85 */
  86
  87        /*
  88         * Register usage at this point:
  89         *
  90         * R1       = host R1
  91         * R2       = host R2
  92         * R3       = trap number on this thread
  93         * R12      = exit handler id
  94         * R13      = PACA
  95         */
  96
  97        /* Restore non-volatile host registers (r14 - r31) and CR */
  98        REST_NVGPRS(r1)
  99        ld      r4, _CCR(r1)
 100        mtcr    r4
 101
 102        addi    r1, r1, SWITCH_FRAME_SIZE
 103        ld      r0, PPC_LR_STKOFF(r1)
 104        mtlr    r0
 105        blr
 106
 107_GLOBAL(kvmhv_save_host_pmu)
 108BEGIN_FTR_SECTION
 109        /* Work around P8 PMAE bug */
 110        li      r3, -1
 111        clrrdi  r3, r3, 10
 112        mfspr   r8, SPRN_MMCR2
 113        mtspr   SPRN_MMCR2, r3          /* freeze all counters using MMCR2 */
 114        isync
 115END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 116        li      r3, 1
 117        sldi    r3, r3, 31              /* MMCR0_FC (freeze counters) bit */
 118        mfspr   r7, SPRN_MMCR0          /* save MMCR0 */
 119        mtspr   SPRN_MMCR0, r3          /* freeze all counters, disable interrupts */
 120        mfspr   r6, SPRN_MMCRA
 121        /* Clear MMCRA in order to disable SDAR updates */
 122        li      r5, 0
 123        mtspr   SPRN_MMCRA, r5
 124        isync
 125        lbz     r5, PACA_PMCINUSE(r13)  /* is the host using the PMU? */
 126        cmpwi   r5, 0
 127        beq     31f                     /* skip if not */
 128        mfspr   r5, SPRN_MMCR1
 129        mfspr   r9, SPRN_SIAR
 130        mfspr   r10, SPRN_SDAR
 131        std     r7, HSTATE_MMCR0(r13)
 132        std     r5, HSTATE_MMCR1(r13)
 133        std     r6, HSTATE_MMCRA(r13)
 134        std     r9, HSTATE_SIAR(r13)
 135        std     r10, HSTATE_SDAR(r13)
 136BEGIN_FTR_SECTION
 137        mfspr   r9, SPRN_SIER
 138        std     r8, HSTATE_MMCR2(r13)
 139        std     r9, HSTATE_SIER(r13)
 140END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
 141BEGIN_FTR_SECTION
 142        mfspr   r5, SPRN_MMCR3
 143        mfspr   r6, SPRN_SIER2
 144        mfspr   r7, SPRN_SIER3
 145        std     r5, HSTATE_MMCR3(r13)
 146        std     r6, HSTATE_SIER2(r13)
 147        std     r7, HSTATE_SIER3(r13)
 148END_FTR_SECTION_IFSET(CPU_FTR_ARCH_31)
 149        mfspr   r3, SPRN_PMC1
 150        mfspr   r5, SPRN_PMC2
 151        mfspr   r6, SPRN_PMC3
 152        mfspr   r7, SPRN_PMC4
 153        mfspr   r8, SPRN_PMC5
 154        mfspr   r9, SPRN_PMC6
 155        stw     r3, HSTATE_PMC1(r13)
 156        stw     r5, HSTATE_PMC2(r13)
 157        stw     r6, HSTATE_PMC3(r13)
 158        stw     r7, HSTATE_PMC4(r13)
 159        stw     r8, HSTATE_PMC5(r13)
 160        stw     r9, HSTATE_PMC6(r13)
 16131:     blr
 162