linux/arch/powerpc/kvm/book3s_hv_interrupts.S
<<
>>
Prefs
   1/*
   2 * This program is free software; you can redistribute it and/or modify
   3 * it under the terms of the GNU General Public License, version 2, as
   4 * published by the Free Software Foundation.
   5 *
   6 * This program is distributed in the hope that it will be useful,
   7 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   8 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   9 * GNU General Public License for more details.
  10 *
  11 * You should have received a copy of the GNU General Public License
  12 * along with this program; if not, write to the Free Software
  13 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  14 *
  15 * Copyright 2011 Paul Mackerras, IBM Corp. <paulus@au1.ibm.com>
  16 *
  17 * Derived from book3s_interrupts.S, which is:
  18 * Copyright SUSE Linux Products GmbH 2009
  19 *
  20 * Authors: Alexander Graf <agraf@suse.de>
  21 */
  22
  23#include <asm/ppc_asm.h>
  24#include <asm/kvm_asm.h>
  25#include <asm/reg.h>
  26#include <asm/page.h>
  27#include <asm/asm-offsets.h>
  28#include <asm/exception-64s.h>
  29#include <asm/ppc-opcode.h>
  30
  31/*****************************************************************************
  32 *                                                                           *
  33 *     Guest entry / exit code that is in kernel module memory (vmalloc)     *
  34 *                                                                           *
  35 ****************************************************************************/
  36
  37/* Registers:
  38 *  r4: vcpu pointer
  39 */
  40_GLOBAL(__kvmppc_vcore_entry)
  41
  42        /* Write correct stack frame */
  43        mflr    r0
  44        std     r0,PPC_LR_STKOFF(r1)
  45
  46        /* Save host state to the stack */
  47        stdu    r1, -SWITCH_FRAME_SIZE(r1)
  48
  49        /* Save non-volatile registers (r14 - r31) and CR */
  50        SAVE_NVGPRS(r1)
  51        mfcr    r3
  52        std     r3, _CCR(r1)
  53
  54        /* Save host DSCR */
  55BEGIN_FTR_SECTION
  56        mfspr   r3, SPRN_DSCR
  57        std     r3, HSTATE_DSCR(r13)
  58END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
  59
  60        /* Save host DABR */
  61        mfspr   r3, SPRN_DABR
  62        std     r3, HSTATE_DABR(r13)
  63
  64        /* Hard-disable interrupts */
  65        mfmsr   r10
  66        std     r10, HSTATE_HOST_MSR(r13)
  67        rldicl  r10,r10,48,1
  68        rotldi  r10,r10,16
  69        mtmsrd  r10,1
  70
  71        /* Save host PMU registers */
  72        /* R4 is live here (vcpu pointer) but not r3 or r5 */
  73        li      r3, 1
  74        sldi    r3, r3, 31              /* MMCR0_FC (freeze counters) bit */
  75        mfspr   r7, SPRN_MMCR0          /* save MMCR0 */
  76        mtspr   SPRN_MMCR0, r3          /* freeze all counters, disable interrupts */
  77        mfspr   r6, SPRN_MMCRA
  78BEGIN_FTR_SECTION
  79        /* On P7, clear MMCRA in order to disable SDAR updates */
  80        li      r5, 0
  81        mtspr   SPRN_MMCRA, r5
  82END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206)
  83        isync
  84        ld      r3, PACALPPACAPTR(r13)  /* is the host using the PMU? */
  85        lbz     r5, LPPACA_PMCINUSE(r3)
  86        cmpwi   r5, 0
  87        beq     31f                     /* skip if not */
  88        mfspr   r5, SPRN_MMCR1
  89        std     r7, HSTATE_MMCR(r13)
  90        std     r5, HSTATE_MMCR + 8(r13)
  91        std     r6, HSTATE_MMCR + 16(r13)
  92        mfspr   r3, SPRN_PMC1
  93        mfspr   r5, SPRN_PMC2
  94        mfspr   r6, SPRN_PMC3
  95        mfspr   r7, SPRN_PMC4
  96        mfspr   r8, SPRN_PMC5
  97        mfspr   r9, SPRN_PMC6
  98BEGIN_FTR_SECTION
  99        mfspr   r10, SPRN_PMC7
 100        mfspr   r11, SPRN_PMC8
 101END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
 102        stw     r3, HSTATE_PMC(r13)
 103        stw     r5, HSTATE_PMC + 4(r13)
 104        stw     r6, HSTATE_PMC + 8(r13)
 105        stw     r7, HSTATE_PMC + 12(r13)
 106        stw     r8, HSTATE_PMC + 16(r13)
 107        stw     r9, HSTATE_PMC + 20(r13)
 108BEGIN_FTR_SECTION
 109        stw     r10, HSTATE_PMC + 24(r13)
 110        stw     r11, HSTATE_PMC + 28(r13)
 111END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
 11231:
 113
 114        /*
 115         * Put whatever is in the decrementer into the
 116         * hypervisor decrementer.
 117         */
 118        mfspr   r8,SPRN_DEC
 119        mftb    r7
 120        mtspr   SPRN_HDEC,r8
 121        extsw   r8,r8
 122        add     r8,r8,r7
 123        std     r8,HSTATE_DECEXP(r13)
 124
 125#ifdef CONFIG_SMP
 126        /*
 127         * On PPC970, if the guest vcpu has an external interrupt pending,
 128         * send ourselves an IPI so as to interrupt the guest once it
 129         * enables interrupts.  (It must have interrupts disabled,
 130         * otherwise we would already have delivered the interrupt.)
 131         *
 132         * XXX If this is a UP build, smp_send_reschedule is not available,
 133         * so the interrupt will be delayed until the next time the vcpu
 134         * enters the guest with interrupts enabled.
 135         */
 136BEGIN_FTR_SECTION
 137        ld      r0, VCPU_PENDING_EXC(r4)
 138        li      r7, (1 << BOOK3S_IRQPRIO_EXTERNAL)
 139        oris    r7, r7, (1 << BOOK3S_IRQPRIO_EXTERNAL_LEVEL)@h
 140        and.    r0, r0, r7
 141        beq     32f
 142        mr      r31, r4
 143        lhz     r3, PACAPACAINDEX(r13)
 144        bl      smp_send_reschedule
 145        nop
 146        mr      r4, r31
 14732:
 148END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
 149#endif /* CONFIG_SMP */
 150
 151        /* Jump to partition switch code */
 152        bl      .kvmppc_hv_entry_trampoline
 153        nop
 154
 155/*
 156 * We return here in virtual mode after the guest exits
 157 * with something that we can't handle in real mode.
 158 * Interrupts are enabled again at this point.
 159 */
 160
 161.global kvmppc_handler_highmem
 162kvmppc_handler_highmem:
 163
 164        /*
 165         * Register usage at this point:
 166         *
 167         * R1       = host R1
 168         * R2       = host R2
 169         * R12      = exit handler id
 170         * R13      = PACA
 171         */
 172
 173        /* Restore non-volatile host registers (r14 - r31) and CR */
 174        REST_NVGPRS(r1)
 175        ld      r4, _CCR(r1)
 176        mtcr    r4
 177
 178        addi    r1, r1, SWITCH_FRAME_SIZE
 179        ld      r0, PPC_LR_STKOFF(r1)
 180        mtlr    r0
 181        blr
 182