Path: blob/master/arch/powerpc/kvm/book3s_hv_rmhandlers.S
26451 views
/* SPDX-License-Identifier: GPL-2.0-only */1/*2*3* Copyright 2011 Paul Mackerras, IBM Corp. <[email protected]>4*5* Derived from book3s_rmhandlers.S and other files, which are:6*7* Copyright SUSE Linux Products GmbH 20098*9* Authors: Alexander Graf <[email protected]>10*/1112#include <linux/export.h>13#include <linux/linkage.h>14#include <linux/objtool.h>15#include <asm/ppc_asm.h>16#include <asm/code-patching-asm.h>17#include <asm/kvm_asm.h>18#include <asm/reg.h>19#include <asm/mmu.h>20#include <asm/page.h>21#include <asm/ptrace.h>22#include <asm/hvcall.h>23#include <asm/asm-offsets.h>24#include <asm/exception-64s.h>25#include <asm/kvm_book3s_asm.h>26#include <asm/book3s/64/mmu-hash.h>27#include <asm/tm.h>28#include <asm/opal.h>29#include <asm/thread_info.h>30#include <asm/asm-compat.h>31#include <asm/feature-fixups.h>32#include <asm/cpuidle.h>3334/* Values in HSTATE_NAPPING(r13) */35#define NAPPING_CEDE 136#define NAPPING_NOVCPU 237#define NAPPING_UNSPLIT 33839/* Stack frame offsets for kvmppc_hv_entry */40#define SFS 16041#define STACK_SLOT_TRAP (SFS-4)42#define STACK_SLOT_TID (SFS-16)43#define STACK_SLOT_PSSCR (SFS-24)44#define STACK_SLOT_PID (SFS-32)45#define STACK_SLOT_IAMR (SFS-40)46#define STACK_SLOT_CIABR (SFS-48)47#define STACK_SLOT_DAWR0 (SFS-56)48#define STACK_SLOT_DAWRX0 (SFS-64)49#define STACK_SLOT_HFSCR (SFS-72)50#define STACK_SLOT_AMR (SFS-80)51#define STACK_SLOT_UAMOR (SFS-88)52#define STACK_SLOT_FSCR (SFS-96)5354/*55* Use the last LPID (all implemented LPID bits = 1) for partition switching.56* This is reserved in the LPID allocator. POWER7 only implements 0x3ff, but57* we write 0xfff into the LPID SPR anyway, which seems to work and just58* ignores the top bits.59*/60#define LPID_RSVD 0xfff6162/*63* Call kvmppc_hv_entry in real mode.64* Must be called with interrupts hard-disabled.65*66* Input Registers:67*68* LR = return address to continue at after eventually re-enabling MMU69*/70_GLOBAL_TOC(kvmppc_hv_entry_trampoline)71mflr r072std r0, PPC_LR_STKOFF(r1)73stdu r1, -112(r1)74mfmsr r1075std r10, HSTATE_HOST_MSR(r13)76LOAD_REG_ADDR(r5, kvmppc_call_hv_entry)77li r0,MSR_RI78andc r0,r10,r079li r6,MSR_IR | MSR_DR80andc r6,r10,r681mtmsrd r0,1 /* clear RI in MSR */82mtsrr0 r583mtsrr1 r684RFI_TO_KERNEL8586kvmppc_call_hv_entry:87ld r4, HSTATE_KVM_VCPU(r13)88bl kvmppc_hv_entry8990/* Back from guest - restore host state and return to caller */9192BEGIN_FTR_SECTION93/* Restore host DABR and DABRX */94ld r5,HSTATE_DABR(r13)95li r6,796mtspr SPRN_DABR,r597mtspr SPRN_DABRX,r698END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)99100/* Restore SPRG3 */101ld r3,PACA_SPRG_VDSO(r13)102mtspr SPRN_SPRG_VDSO_WRITE,r3103104/* Reload the host's PMU registers */105bl kvmhv_load_host_pmu106107/*108* Reload DEC. HDEC interrupts were disabled when109* we reloaded the host's LPCR value.110*/111ld r3, HSTATE_DECEXP(r13)112mftb r4113subf r4, r4, r3114mtspr SPRN_DEC, r4115116/* hwthread_req may have got set by cede or no vcpu, so clear it */117li r0, 0118stb r0, HSTATE_HWTHREAD_REQ(r13)119120/*121* For external interrupts we need to call the Linux122* handler to process the interrupt. We do that by jumping123* to absolute address 0x500 for external interrupts.124* The [h]rfid at the end of the handler will return to125* the book3s_hv_interrupts.S code. For other interrupts126* we do the rfid to get back to the book3s_hv_interrupts.S127* code here.128*/129ld r8, 112+PPC_LR_STKOFF(r1)130addi r1, r1, 112131ld r7, HSTATE_HOST_MSR(r13)132133/* Return the trap number on this thread as the return value */134mr r3, r12135136/* RFI into the highmem handler */137mfmsr r6138li r0, MSR_RI139andc r6, r6, r0140mtmsrd r6, 1 /* Clear RI in MSR */141mtsrr0 r8142mtsrr1 r7143RFI_TO_KERNEL144145kvmppc_primary_no_guest:146/* We handle this much like a ceded vcpu */147/* put the HDEC into the DEC, since HDEC interrupts don't wake us */148/* HDEC may be larger than DEC for arch >= v3.00, but since the */149/* HDEC value came from DEC in the first place, it will fit */150mfspr r3, SPRN_HDEC151mtspr SPRN_DEC, r3152/*153* Make sure the primary has finished the MMU switch.154* We should never get here on a secondary thread, but155* check it for robustness' sake.156*/157ld r5, HSTATE_KVM_VCORE(r13)15865: lbz r0, VCORE_IN_GUEST(r5)159cmpwi r0, 0160beq 65b161/* Set LPCR. */162ld r8,VCORE_LPCR(r5)163mtspr SPRN_LPCR,r8164isync165/* set our bit in napping_threads */166ld r5, HSTATE_KVM_VCORE(r13)167lbz r7, HSTATE_PTID(r13)168li r0, 1169sld r0, r0, r7170addi r6, r5, VCORE_NAPPING_THREADS1711: lwarx r3, 0, r6172or r3, r3, r0173stwcx. r3, 0, r6174bne 1b175/* order napping_threads update vs testing entry_exit_map */176isync177li r12, 0178lwz r7, VCORE_ENTRY_EXIT(r5)179cmpwi r7, 0x100180bge kvm_novcpu_exit /* another thread already exiting */181li r3, NAPPING_NOVCPU182stb r3, HSTATE_NAPPING(r13)183184li r3, 0 /* Don't wake on privileged (OS) doorbell */185b kvm_do_nap186187/*188* kvm_novcpu_wakeup189* Entered from kvm_start_guest if kvm_hstate.napping is set190* to NAPPING_NOVCPU191* r2 = kernel TOC192* r13 = paca193*/194kvm_novcpu_wakeup:195ld r1, HSTATE_HOST_R1(r13)196ld r5, HSTATE_KVM_VCORE(r13)197li r0, 0198stb r0, HSTATE_NAPPING(r13)199200/* check the wake reason */201bl kvmppc_check_wake_reason202203/*204* Restore volatile registers since we could have called205* a C routine in kvmppc_check_wake_reason.206* r5 = VCORE207*/208ld r5, HSTATE_KVM_VCORE(r13)209210/* see if any other thread is already exiting */211lwz r0, VCORE_ENTRY_EXIT(r5)212cmpwi r0, 0x100213bge kvm_novcpu_exit214215/* clear our bit in napping_threads */216lbz r7, HSTATE_PTID(r13)217li r0, 1218sld r0, r0, r7219addi r6, r5, VCORE_NAPPING_THREADS2204: lwarx r7, 0, r6221andc r7, r7, r0222stwcx. r7, 0, r6223bne 4b224225/* See if the wake reason means we need to exit */226cmpdi r3, 0227bge kvm_novcpu_exit228229/* See if our timeslice has expired (HDEC is negative) */230mfspr r0, SPRN_HDEC231extsw r0, r0232li r12, BOOK3S_INTERRUPT_HV_DECREMENTER233cmpdi r0, 0234blt kvm_novcpu_exit235236/* Got an IPI but other vcpus aren't yet exiting, must be a latecomer */237ld r4, HSTATE_KVM_VCPU(r13)238cmpdi r4, 0239beq kvmppc_primary_no_guest240241#ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING242addi r3, r4, VCPU_TB_RMENTRY243bl kvmhv_start_timing244#endif245b kvmppc_got_guest246247kvm_novcpu_exit:248#ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING249ld r4, HSTATE_KVM_VCPU(r13)250cmpdi r4, 0251beq 13f252addi r3, r4, VCPU_TB_RMEXIT253bl kvmhv_accumulate_time254#endif25513: mr r3, r12256stw r12, STACK_SLOT_TRAP(r1)257bl kvmhv_commence_exit258nop259b kvmhv_switch_to_host260261/*262* We come in here when wakened from Linux offline idle code.263* Relocation is off264* r3 contains the SRR1 wakeup value, SRR1 is trashed.265*/266_GLOBAL(idle_kvm_start_guest)267mfcr r5268mflr r0269std r5, 8(r1) // Save CR in caller's frame270std r0, 16(r1) // Save LR in caller's frame271// Create frame on emergency stack272ld r4, PACAEMERGSP(r13)273stdu r1, -SWITCH_FRAME_SIZE(r4)274// Switch to new frame on emergency stack275mr r1, r4276std r3, 32(r1) // Save SRR1 wakeup value277SAVE_NVGPRS(r1)278279/*280* Could avoid this and pass it through in r3. For now,281* code expects it to be in SRR1.282*/283mtspr SPRN_SRR1,r3284285li r0,0286stb r0,PACA_FTRACE_ENABLED(r13)287288li r0,KVM_HWTHREAD_IN_KVM289stb r0,HSTATE_HWTHREAD_STATE(r13)290291/* kvm cede / napping does not come through here */292lbz r0,HSTATE_NAPPING(r13)293twnei r0,0294295b 1f296297kvm_unsplit_wakeup:298li r0, 0299stb r0, HSTATE_NAPPING(r13)3003011:302303/*304* We weren't napping due to cede, so this must be a secondary305* thread being woken up to run a guest, or being woken up due306* to a stray IPI. (Or due to some machine check or hypervisor307* maintenance interrupt while the core is in KVM.)308*/309310/* Check the wake reason in SRR1 to see why we got here */311bl kvmppc_check_wake_reason312/*313* kvmppc_check_wake_reason could invoke a C routine, but we314* have no volatile registers to restore when we return.315*/316317cmpdi r3, 0318bge kvm_no_guest319320/* get vcore pointer, NULL if we have nothing to run */321ld r5,HSTATE_KVM_VCORE(r13)322cmpdi r5,0323/* if we have no vcore to run, go back to sleep */324beq kvm_no_guest325326kvm_secondary_got_guest:327328// About to go to guest, clear saved SRR1329li r0, 0330std r0, 32(r1)331332/* Set HSTATE_DSCR(r13) to something sensible */333ld r6, PACA_DSCR_DEFAULT(r13)334std r6, HSTATE_DSCR(r13)335336/* On thread 0 of a subcore, set HDEC to max */337lbz r4, HSTATE_PTID(r13)338cmpwi r4, 0339bne 63f340lis r6,0x7fff /* MAX_INT@h */341mtspr SPRN_HDEC, r6342/* and set per-LPAR registers, if doing dynamic micro-threading */343ld r6, HSTATE_SPLIT_MODE(r13)344cmpdi r6, 0345beq 63f346ld r0, KVM_SPLIT_RPR(r6)347mtspr SPRN_RPR, r0348ld r0, KVM_SPLIT_PMMAR(r6)349mtspr SPRN_PMMAR, r0350ld r0, KVM_SPLIT_LDBAR(r6)351mtspr SPRN_LDBAR, r0352isync35363:354/* Order load of vcpu after load of vcore */355lwsync356ld r4, HSTATE_KVM_VCPU(r13)357bl kvmppc_hv_entry358359/* Back from the guest, go back to nap */360/* Clear our vcpu and vcore pointers so we don't come back in early */361li r0, 0362std r0, HSTATE_KVM_VCPU(r13)363/*364* Once we clear HSTATE_KVM_VCORE(r13), the code in365* kvmppc_run_core() is going to assume that all our vcpu366* state is visible in memory. This lwsync makes sure367* that that is true.368*/369lwsync370std r0, HSTATE_KVM_VCORE(r13)371372/*373* All secondaries exiting guest will fall through this path.374* Before proceeding, just check for HMI interrupt and375* invoke opal hmi handler. By now we are sure that the376* primary thread on this core/subcore has already made partition377* switch/TB resync and we are good to call opal hmi handler.378*/379cmpwi r12, BOOK3S_INTERRUPT_HMI380bne kvm_no_guest381382li r3,0 /* NULL argument */383bl CFUNC(hmi_exception_realmode)384/*385* At this point we have finished executing in the guest.386* We need to wait for hwthread_req to become zero, since387* we may not turn on the MMU while hwthread_req is non-zero.388* While waiting we also need to check if we get given a vcpu to run.389*/390kvm_no_guest:391lbz r3, HSTATE_HWTHREAD_REQ(r13)392cmpwi r3, 0393bne 53f394HMT_MEDIUM395li r0, KVM_HWTHREAD_IN_KERNEL396stb r0, HSTATE_HWTHREAD_STATE(r13)397/* need to recheck hwthread_req after a barrier, to avoid race */398sync399lbz r3, HSTATE_HWTHREAD_REQ(r13)400cmpwi r3, 0401bne 54f402403/*404* Jump to idle_return_gpr_loss, which returns to the405* idle_kvm_start_guest caller.406*/407li r3, LPCR_PECE0408mfspr r4, SPRN_LPCR409rlwimi r4, r3, 0, LPCR_PECE0 | LPCR_PECE1410mtspr SPRN_LPCR, r4411// Return SRR1 wakeup value, or 0 if we went into the guest412ld r3, 32(r1)413REST_NVGPRS(r1)414ld r1, 0(r1) // Switch back to caller stack415ld r0, 16(r1) // Reload LR416ld r5, 8(r1) // Reload CR417mtlr r0418mtcr r5419blr42042153:422HMT_LOW423ld r5, HSTATE_KVM_VCORE(r13)424cmpdi r5, 0425bne 60f426ld r3, HSTATE_SPLIT_MODE(r13)427cmpdi r3, 0428beq kvm_no_guest429lbz r0, KVM_SPLIT_DO_NAP(r3)430cmpwi r0, 0431beq kvm_no_guest432HMT_MEDIUM433b kvm_unsplit_nap43460: HMT_MEDIUM435b kvm_secondary_got_guest43643754: li r0, KVM_HWTHREAD_IN_KVM438stb r0, HSTATE_HWTHREAD_STATE(r13)439b kvm_no_guest440441/*442* Here the primary thread is trying to return the core to443* whole-core mode, so we need to nap.444*/445kvm_unsplit_nap:446/*447* When secondaries are napping in kvm_unsplit_nap() with448* hwthread_req = 1, HMI goes ignored even though subcores are449* already exited the guest. Hence HMI keeps waking up secondaries450* from nap in a loop and secondaries always go back to nap since451* no vcore is assigned to them. This makes impossible for primary452* thread to get hold of secondary threads resulting into a soft453* lockup in KVM path.454*455* Let us check if HMI is pending and handle it before we go to nap.456*/457cmpwi r12, BOOK3S_INTERRUPT_HMI458bne 55f459li r3, 0 /* NULL argument */460bl CFUNC(hmi_exception_realmode)46155:462/*463* Ensure that secondary doesn't nap when it has464* its vcore pointer set.465*/466sync /* matches smp_mb() before setting split_info.do_nap */467ld r0, HSTATE_KVM_VCORE(r13)468cmpdi r0, 0469bne kvm_no_guest470/* clear any pending message */471BEGIN_FTR_SECTION472lis r6, (PPC_DBELL_SERVER << (63-36))@h473PPC_MSGCLR(6)474END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)475/* Set kvm_split_mode.napped[tid] = 1 */476ld r3, HSTATE_SPLIT_MODE(r13)477li r0, 1478lhz r4, PACAPACAINDEX(r13)479clrldi r4, r4, 61 /* micro-threading => P8 => 8 threads/core */480addi r4, r4, KVM_SPLIT_NAPPED481stbx r0, r3, r4482/* Check the do_nap flag again after setting napped[] */483sync484lbz r0, KVM_SPLIT_DO_NAP(r3)485cmpwi r0, 0486beq 57f487li r3, NAPPING_UNSPLIT488stb r3, HSTATE_NAPPING(r13)489li r3, (LPCR_PECEDH | LPCR_PECE0) >> 4490mfspr r5, SPRN_LPCR491rlwimi r5, r3, 4, (LPCR_PECEDP | LPCR_PECEDH | LPCR_PECE0 | LPCR_PECE1)492b kvm_nap_sequence49349457: li r0, 0495stbx r0, r3, r4496b kvm_no_guest497498/******************************************************************************499* *500* Entry code *501* *502*****************************************************************************/503504SYM_CODE_START_LOCAL(kvmppc_hv_entry)505506/* Required state:507*508* R4 = vcpu pointer (or NULL)509* MSR = ~IR|DR510* R13 = PACA511* R1 = host R1512* R2 = TOC513* all other volatile GPRS = free514* Does not preserve non-volatile GPRs or CR fields515*/516mflr r0517std r0, PPC_LR_STKOFF(r1)518stdu r1, -SFS(r1)519520/* Save R1 in the PACA */521std r1, HSTATE_HOST_R1(r13)522523li r6, KVM_GUEST_MODE_HOST_HV524stb r6, HSTATE_IN_GUEST(r13)525526#ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING527/* Store initial timestamp */528cmpdi r4, 0529beq 1f530addi r3, r4, VCPU_TB_RMENTRY531bl kvmhv_start_timing5321:533#endif534535ld r5, HSTATE_KVM_VCORE(r13)536ld r9, VCORE_KVM(r5) /* pointer to struct kvm */537538/*539* POWER7/POWER8 host -> guest partition switch code.540* We don't have to lock against concurrent tlbies,541* but we do have to coordinate across hardware threads.542*/543/* Set bit in entry map iff exit map is zero. */544li r7, 1545lbz r6, HSTATE_PTID(r13)546sld r7, r7, r6547addi r8, r5, VCORE_ENTRY_EXIT54821: lwarx r3, 0, r8549cmpwi r3, 0x100 /* any threads starting to exit? */550bge secondary_too_late /* if so we're too late to the party */551or r3, r3, r7552stwcx. r3, 0, r8553bne 21b554555/* Primary thread switches to guest partition. */556cmpwi r6,0557bne 10f558559lwz r7,KVM_LPID(r9)560ld r6,KVM_SDR1(r9)561li r0,LPID_RSVD /* switch to reserved LPID */562mtspr SPRN_LPID,r0563ptesync564mtspr SPRN_SDR1,r6 /* switch to partition page table */565mtspr SPRN_LPID,r7566isync567568/* See if we need to flush the TLB. */569mr r3, r9 /* kvm pointer */570lhz r4, PACAPACAINDEX(r13) /* physical cpu number */571li r5, 0 /* nested vcpu pointer */572bl kvmppc_check_need_tlb_flush573nop574ld r5, HSTATE_KVM_VCORE(r13)575576/* Add timebase offset onto timebase */57722: ld r8,VCORE_TB_OFFSET(r5)578cmpdi r8,0579beq 37f580std r8, VCORE_TB_OFFSET_APPL(r5)581mftb r6 /* current host timebase */582add r8,r8,r6583mtspr SPRN_TBU40,r8 /* update upper 40 bits */584mftb r7 /* check if lower 24 bits overflowed */585clrldi r6,r6,40586clrldi r7,r7,40587cmpld r7,r6588bge 37f589addis r8,r8,0x100 /* if so, increment upper 40 bits */590mtspr SPRN_TBU40,r8591592/* Load guest PCR value to select appropriate compat mode */59337: ld r7, VCORE_PCR(r5)594LOAD_REG_IMMEDIATE(r6, PCR_MASK)595cmpld r7, r6596beq 38f597or r7, r7, r6598mtspr SPRN_PCR, r759938:600601BEGIN_FTR_SECTION602/* DPDES and VTB are shared between threads */603ld r8, VCORE_DPDES(r5)604ld r7, VCORE_VTB(r5)605mtspr SPRN_DPDES, r8606mtspr SPRN_VTB, r7607END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)608609/* Mark the subcore state as inside guest */610bl kvmppc_subcore_enter_guest611nop612ld r5, HSTATE_KVM_VCORE(r13)613ld r4, HSTATE_KVM_VCPU(r13)614li r0,1615stb r0,VCORE_IN_GUEST(r5) /* signal secondaries to continue */616617/* Do we have a guest vcpu to run? */61810: cmpdi r4, 0619beq kvmppc_primary_no_guest620kvmppc_got_guest:621/* Increment yield count if they have a VPA */622ld r3, VCPU_VPA(r4)623cmpdi r3, 0624beq 25f625li r6, LPPACA_YIELDCOUNT626LWZX_BE r5, r3, r6627addi r5, r5, 1628STWX_BE r5, r3, r6629li r6, 1630stb r6, VCPU_VPA_DIRTY(r4)63125:632633/* Save purr/spurr */634mfspr r5,SPRN_PURR635mfspr r6,SPRN_SPURR636std r5,HSTATE_PURR(r13)637std r6,HSTATE_SPURR(r13)638ld r7,VCPU_PURR(r4)639ld r8,VCPU_SPURR(r4)640mtspr SPRN_PURR,r7641mtspr SPRN_SPURR,r8642643/* Save host values of some registers */644BEGIN_FTR_SECTION645mfspr r5, SPRN_CIABR646mfspr r6, SPRN_DAWR0647mfspr r7, SPRN_DAWRX0648mfspr r8, SPRN_IAMR649std r5, STACK_SLOT_CIABR(r1)650std r6, STACK_SLOT_DAWR0(r1)651std r7, STACK_SLOT_DAWRX0(r1)652std r8, STACK_SLOT_IAMR(r1)653mfspr r5, SPRN_FSCR654std r5, STACK_SLOT_FSCR(r1)655END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)656657mfspr r5, SPRN_AMR658std r5, STACK_SLOT_AMR(r1)659mfspr r6, SPRN_UAMOR660std r6, STACK_SLOT_UAMOR(r1)661662BEGIN_FTR_SECTION663/* Set partition DABR */664/* Do this before re-enabling PMU to avoid P7 DABR corruption bug */665lwz r5,VCPU_DABRX(r4)666ld r6,VCPU_DABR(r4)667mtspr SPRN_DABRX,r5668mtspr SPRN_DABR,r6669isync670END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)671672#ifdef CONFIG_PPC_TRANSACTIONAL_MEM673BEGIN_FTR_SECTION674b 91f675END_FTR_SECTION_IFCLR(CPU_FTR_TM)676/*677* NOTE THAT THIS TRASHES ALL NON-VOLATILE REGISTERS (but not CR)678*/679mr r3, r4680ld r4, VCPU_MSR(r3)681li r5, 0 /* don't preserve non-vol regs */682bl kvmppc_restore_tm_hv683nop684ld r4, HSTATE_KVM_VCPU(r13)68591:686#endif687688/* Load guest PMU registers; r4 = vcpu pointer here */689mr r3, r4690bl kvmhv_load_guest_pmu691692/* Load up FP, VMX and VSX registers */693ld r4, HSTATE_KVM_VCPU(r13)694bl kvmppc_load_fp695696ld r14, VCPU_GPR(R14)(r4)697ld r15, VCPU_GPR(R15)(r4)698ld r16, VCPU_GPR(R16)(r4)699ld r17, VCPU_GPR(R17)(r4)700ld r18, VCPU_GPR(R18)(r4)701ld r19, VCPU_GPR(R19)(r4)702ld r20, VCPU_GPR(R20)(r4)703ld r21, VCPU_GPR(R21)(r4)704ld r22, VCPU_GPR(R22)(r4)705ld r23, VCPU_GPR(R23)(r4)706ld r24, VCPU_GPR(R24)(r4)707ld r25, VCPU_GPR(R25)(r4)708ld r26, VCPU_GPR(R26)(r4)709ld r27, VCPU_GPR(R27)(r4)710ld r28, VCPU_GPR(R28)(r4)711ld r29, VCPU_GPR(R29)(r4)712ld r30, VCPU_GPR(R30)(r4)713ld r31, VCPU_GPR(R31)(r4)714715/* Switch DSCR to guest value */716ld r5, VCPU_DSCR(r4)717mtspr SPRN_DSCR, r5718719BEGIN_FTR_SECTION720/* Skip next section on POWER7 */721b 8f722END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)723/* Load up POWER8-specific registers */724ld r5, VCPU_IAMR(r4)725lwz r6, VCPU_PSPB(r4)726ld r7, VCPU_FSCR(r4)727mtspr SPRN_IAMR, r5728mtspr SPRN_PSPB, r6729mtspr SPRN_FSCR, r7730/*731* Handle broken DAWR case by not writing it. This means we732* can still store the DAWR register for migration.733*/734LOAD_REG_ADDR(r5, dawr_force_enable)735lbz r5, 0(r5)736cmpdi r5, 0737beq 1f738ld r5, VCPU_DAWR0(r4)739ld r6, VCPU_DAWRX0(r4)740mtspr SPRN_DAWR0, r5741mtspr SPRN_DAWRX0, r67421:743ld r7, VCPU_CIABR(r4)744ld r8, VCPU_TAR(r4)745mtspr SPRN_CIABR, r7746mtspr SPRN_TAR, r8747ld r5, VCPU_IC(r4)748ld r8, VCPU_EBBHR(r4)749mtspr SPRN_IC, r5750mtspr SPRN_EBBHR, r8751ld r5, VCPU_EBBRR(r4)752ld r6, VCPU_BESCR(r4)753lwz r7, VCPU_GUEST_PID(r4)754ld r8, VCPU_WORT(r4)755mtspr SPRN_EBBRR, r5756mtspr SPRN_BESCR, r6757mtspr SPRN_PID, r7758mtspr SPRN_WORT, r8759/* POWER8-only registers */760ld r5, VCPU_TCSCR(r4)761ld r6, VCPU_ACOP(r4)762ld r7, VCPU_CSIGR(r4)763ld r8, VCPU_TACR(r4)764mtspr SPRN_TCSCR, r5765mtspr SPRN_ACOP, r6766mtspr SPRN_CSIGR, r7767mtspr SPRN_TACR, r8768nop7698:770771ld r5, VCPU_SPRG0(r4)772ld r6, VCPU_SPRG1(r4)773ld r7, VCPU_SPRG2(r4)774ld r8, VCPU_SPRG3(r4)775mtspr SPRN_SPRG0, r5776mtspr SPRN_SPRG1, r6777mtspr SPRN_SPRG2, r7778mtspr SPRN_SPRG3, r8779780/* Load up DAR and DSISR */781ld r5, VCPU_DAR(r4)782lwz r6, VCPU_DSISR(r4)783mtspr SPRN_DAR, r5784mtspr SPRN_DSISR, r6785786/* Restore AMR and UAMOR, set AMOR to all 1s */787ld r5,VCPU_AMR(r4)788ld r6,VCPU_UAMOR(r4)789mtspr SPRN_AMR,r5790mtspr SPRN_UAMOR,r6791792/* Restore state of CTRL run bit; the host currently has it set to 1 */793lwz r5,VCPU_CTRL(r4)794andi. r5,r5,1795bne 4f796li r6,0797mtspr SPRN_CTRLT,r67984:799/* Secondary threads wait for primary to have done partition switch */800ld r5, HSTATE_KVM_VCORE(r13)801lbz r6, HSTATE_PTID(r13)802cmpwi r6, 0803beq 21f804lbz r0, VCORE_IN_GUEST(r5)805cmpwi r0, 0806bne 21f807HMT_LOW80820: lwz r3, VCORE_ENTRY_EXIT(r5)809cmpwi r3, 0x100810bge no_switch_exit811lbz r0, VCORE_IN_GUEST(r5)812cmpwi r0, 0813beq 20b814HMT_MEDIUM81521:816/* Set LPCR. */817ld r8,VCORE_LPCR(r5)818mtspr SPRN_LPCR,r8819isync820821/*822* Set the decrementer to the guest decrementer.823*/824ld r8,VCPU_DEC_EXPIRES(r4)825mftb r7826subf r3,r7,r8827mtspr SPRN_DEC,r3828829/* Check if HDEC expires soon */830mfspr r3, SPRN_HDEC831extsw r3, r3832cmpdi r3, 512 /* 1 microsecond */833blt hdec_soon834835/* Clear out and reload the SLB */836li r6, 0837slbmte r6, r6838PPC_SLBIA(6)839ptesync840841/* Load up guest SLB entries (N.B. slb_max will be 0 for radix) */842lwz r5,VCPU_SLB_MAX(r4)843cmpwi r5,0844beq 9f845mtctr r5846addi r6,r4,VCPU_SLB8471: ld r8,VCPU_SLB_E(r6)848ld r9,VCPU_SLB_V(r6)849slbmte r9,r8850addi r6,r6,VCPU_SLB_SIZE851bdnz 1b8529:853854deliver_guest_interrupt: /* r4 = vcpu, r13 = paca */855/* Check if we can deliver an external or decrementer interrupt now */856ld r0, VCPU_PENDING_EXC(r4)857cmpdi r0, 0858beq 71f859mr r3, r4860bl CFUNC(kvmppc_guest_entry_inject_int)861ld r4, HSTATE_KVM_VCPU(r13)86271:863ld r6, VCPU_SRR0(r4)864ld r7, VCPU_SRR1(r4)865mtspr SPRN_SRR0, r6866mtspr SPRN_SRR1, r7867868ld r10, VCPU_PC(r4)869ld r11, VCPU_MSR(r4)870/* r11 = vcpu->arch.msr & ~MSR_HV */871rldicl r11, r11, 63 - MSR_HV_LG, 1872rotldi r11, r11, 1 + MSR_HV_LG873ori r11, r11, MSR_ME874875ld r6, VCPU_CTR(r4)876ld r7, VCPU_XER(r4)877mtctr r6878mtxer r7879880/*881* Required state:882* R4 = vcpu883* R10: value for HSRR0884* R11: value for HSRR1885* R13 = PACA886*/887fast_guest_return:888li r0,0889stb r0,VCPU_CEDED(r4) /* cancel cede */890mtspr SPRN_HSRR0,r10891mtspr SPRN_HSRR1,r11892893/* Activate guest mode, so faults get handled by KVM */894li r9, KVM_GUEST_MODE_GUEST_HV895stb r9, HSTATE_IN_GUEST(r13)896897#ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING898/* Accumulate timing */899addi r3, r4, VCPU_TB_GUEST900bl kvmhv_accumulate_time901#endif902903/* Enter guest */904905BEGIN_FTR_SECTION906ld r5, VCPU_CFAR(r4)907mtspr SPRN_CFAR, r5908END_FTR_SECTION_IFSET(CPU_FTR_CFAR)909BEGIN_FTR_SECTION910ld r0, VCPU_PPR(r4)911END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)912913ld r5, VCPU_LR(r4)914mtlr r5915916ld r1, VCPU_GPR(R1)(r4)917ld r5, VCPU_GPR(R5)(r4)918ld r8, VCPU_GPR(R8)(r4)919ld r9, VCPU_GPR(R9)(r4)920ld r10, VCPU_GPR(R10)(r4)921ld r11, VCPU_GPR(R11)(r4)922ld r12, VCPU_GPR(R12)(r4)923ld r13, VCPU_GPR(R13)(r4)924925BEGIN_FTR_SECTION926mtspr SPRN_PPR, r0927END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)928929ld r6, VCPU_GPR(R6)(r4)930ld r7, VCPU_GPR(R7)(r4)931932ld r0, VCPU_CR(r4)933mtcr r0934935ld r0, VCPU_GPR(R0)(r4)936ld r2, VCPU_GPR(R2)(r4)937ld r3, VCPU_GPR(R3)(r4)938ld r4, VCPU_GPR(R4)(r4)939HRFI_TO_GUEST940b .941SYM_CODE_END(kvmppc_hv_entry)942943secondary_too_late:944li r12, 0945stw r12, STACK_SLOT_TRAP(r1)946cmpdi r4, 0947beq 11f948stw r12, VCPU_TRAP(r4)949#ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING950addi r3, r4, VCPU_TB_RMEXIT951bl kvmhv_accumulate_time952#endif95311: b kvmhv_switch_to_host954955no_switch_exit:956HMT_MEDIUM957li r12, 0958b 12f959hdec_soon:960li r12, BOOK3S_INTERRUPT_HV_DECREMENTER96112: stw r12, VCPU_TRAP(r4)962mr r9, r4963#ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING964addi r3, r4, VCPU_TB_RMEXIT965bl kvmhv_accumulate_time966#endif967b guest_bypass968969/******************************************************************************970* *971* Exit code *972* *973*****************************************************************************/974975/*976* We come here from the first-level interrupt handlers.977*/978.globl kvmppc_interrupt_hv979kvmppc_interrupt_hv:980/*981* Register contents:982* R9 = HSTATE_IN_GUEST983* R12 = (guest CR << 32) | interrupt vector984* R13 = PACA985* guest R12 saved in shadow VCPU SCRATCH0986* guest R13 saved in SPRN_SCRATCH0987* guest R9 saved in HSTATE_SCRATCH2988*/989/* We're now back in the host but in guest MMU context */990cmpwi r9,KVM_GUEST_MODE_HOST_HV991beq kvmppc_bad_host_intr992li r9, KVM_GUEST_MODE_HOST_HV993stb r9, HSTATE_IN_GUEST(r13)994995ld r9, HSTATE_KVM_VCPU(r13)996997/* Save registers */998999std r0, VCPU_GPR(R0)(r9)1000std r1, VCPU_GPR(R1)(r9)1001std r2, VCPU_GPR(R2)(r9)1002std r3, VCPU_GPR(R3)(r9)1003std r4, VCPU_GPR(R4)(r9)1004std r5, VCPU_GPR(R5)(r9)1005std r6, VCPU_GPR(R6)(r9)1006std r7, VCPU_GPR(R7)(r9)1007std r8, VCPU_GPR(R8)(r9)1008ld r0, HSTATE_SCRATCH2(r13)1009std r0, VCPU_GPR(R9)(r9)1010std r10, VCPU_GPR(R10)(r9)1011std r11, VCPU_GPR(R11)(r9)1012ld r3, HSTATE_SCRATCH0(r13)1013std r3, VCPU_GPR(R12)(r9)1014/* CR is in the high half of r12 */1015srdi r4, r12, 321016std r4, VCPU_CR(r9)1017BEGIN_FTR_SECTION1018ld r3, HSTATE_CFAR(r13)1019std r3, VCPU_CFAR(r9)1020END_FTR_SECTION_IFSET(CPU_FTR_CFAR)1021BEGIN_FTR_SECTION1022ld r4, HSTATE_PPR(r13)1023std r4, VCPU_PPR(r9)1024END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)10251026/* Restore R1/R2 so we can handle faults */1027ld r1, HSTATE_HOST_R1(r13)1028LOAD_PACA_TOC()10291030mfspr r10, SPRN_SRR01031mfspr r11, SPRN_SRR11032std r10, VCPU_SRR0(r9)1033std r11, VCPU_SRR1(r9)1034/* trap is in the low half of r12, clear CR from the high half */1035clrldi r12, r12, 321036andi. r0, r12, 2 /* need to read HSRR0/1? */1037beq 1f1038mfspr r10, SPRN_HSRR01039mfspr r11, SPRN_HSRR11040clrrdi r12, r12, 210411: std r10, VCPU_PC(r9)1042std r11, VCPU_MSR(r9)10431044GET_SCRATCH0(r3)1045mflr r41046std r3, VCPU_GPR(R13)(r9)1047std r4, VCPU_LR(r9)10481049stw r12,VCPU_TRAP(r9)10501051/*1052* Now that we have saved away SRR0/1 and HSRR0/1,1053* interrupts are recoverable in principle, so set MSR_RI.1054* This becomes important for relocation-on interrupts from1055* the guest, which we can get in radix mode on POWER9.1056*/1057li r0, MSR_RI1058mtmsrd r0, 110591060#ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING1061addi r3, r9, VCPU_TB_RMINTR1062mr r4, r91063bl kvmhv_accumulate_time1064ld r5, VCPU_GPR(R5)(r9)1065ld r6, VCPU_GPR(R6)(r9)1066ld r7, VCPU_GPR(R7)(r9)1067ld r8, VCPU_GPR(R8)(r9)1068#endif10691070/* Save HEIR (HV emulation assist reg) in emul_inst1071if this is an HEI (HV emulation interrupt, e40) */1072li r3,KVM_INST_FETCH_FAILED1073std r3,VCPU_LAST_INST(r9)1074cmpwi r12,BOOK3S_INTERRUPT_H_EMUL_ASSIST1075bne 11f1076mfspr r3,SPRN_HEIR107711: std r3,VCPU_HEIR(r9)10781079/* these are volatile across C function calls */1080mfctr r31081mfxer r41082std r3, VCPU_CTR(r9)1083std r4, VCPU_XER(r9)10841085/* Save more register state */1086mfdar r31087mfdsisr r41088std r3, VCPU_DAR(r9)1089stw r4, VCPU_DSISR(r9)10901091/* If this is a page table miss then see if it's theirs or ours */1092cmpwi r12, BOOK3S_INTERRUPT_H_DATA_STORAGE1093beq kvmppc_hdsi1094std r3, VCPU_FAULT_DAR(r9)1095stw r4, VCPU_FAULT_DSISR(r9)1096cmpwi r12, BOOK3S_INTERRUPT_H_INST_STORAGE1097beq kvmppc_hisi10981099/* See if this is a leftover HDEC interrupt */1100cmpwi r12,BOOK3S_INTERRUPT_HV_DECREMENTER1101bne 2f1102mfspr r3,SPRN_HDEC1103extsw r3, r31104cmpdi r3,01105mr r4,r91106bge fast_guest_return11072:1108/* See if this is an hcall we can handle in real mode */1109cmpwi r12,BOOK3S_INTERRUPT_SYSCALL1110beq hcall_try_real_mode11111112/* Hypervisor doorbell - exit only if host IPI flag set */1113cmpwi r12, BOOK3S_INTERRUPT_H_DOORBELL1114bne 3f1115lbz r0, HSTATE_HOST_IPI(r13)1116cmpwi r0, 01117beq maybe_reenter_guest1118b guest_exit_cont11193:1120/* If it's a hypervisor facility unavailable interrupt, save HFSCR */1121cmpwi r12, BOOK3S_INTERRUPT_H_FAC_UNAVAIL1122bne 14f1123mfspr r3, SPRN_HFSCR1124std r3, VCPU_HFSCR(r9)1125b guest_exit_cont112614:1127/* External interrupt ? */1128cmpwi r12, BOOK3S_INTERRUPT_EXTERNAL1129beq kvmppc_guest_external1130/* See if it is a machine check */1131cmpwi r12, BOOK3S_INTERRUPT_MACHINE_CHECK1132beq machine_check_realmode1133/* Or a hypervisor maintenance interrupt */1134cmpwi r12, BOOK3S_INTERRUPT_HMI1135beq hmi_realmode11361137guest_exit_cont: /* r9 = vcpu, r12 = trap, r13 = paca */11381139#ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING1140addi r3, r9, VCPU_TB_RMEXIT1141mr r4, r91142bl kvmhv_accumulate_time1143#endif11441145/*1146* Possibly flush the link stack here, before we do a blr in1147* kvmhv_switch_to_host.1148*/11491: nop1150patch_site 1b patch__call_kvm_flush_link_stack11511152/* For hash guest, read the guest SLB and save it away */1153li r5, 01154lwz r0,VCPU_SLB_NR(r9) /* number of entries in SLB */1155mtctr r01156li r6,01157addi r7,r9,VCPU_SLB11581: slbmfee r8,r61159andis. r0,r8,SLB_ESID_V@h1160beq 2f1161add r8,r8,r6 /* put index in */1162slbmfev r3,r61163std r8,VCPU_SLB_E(r7)1164std r3,VCPU_SLB_V(r7)1165addi r7,r7,VCPU_SLB_SIZE1166addi r5,r5,111672: addi r6,r6,11168bdnz 1b1169/* Finally clear out the SLB */1170li r0,01171slbmte r0,r01172PPC_SLBIA(6)1173ptesync1174stw r5,VCPU_SLB_MAX(r9)11751176/* load host SLB entries */1177ld r8,PACA_SLBSHADOWPTR(r13)11781179.rept SLB_NUM_BOLTED1180li r3, SLBSHADOW_SAVEAREA1181LDX_BE r5, r8, r31182addi r3, r3, 81183LDX_BE r6, r8, r31184andis. r7,r5,SLB_ESID_V@h1185beq 1f1186slbmte r6,r511871: addi r8,r8,161188.endr11891190guest_bypass:1191stw r12, STACK_SLOT_TRAP(r1)11921193/* Save DEC */1194/* Do this before kvmhv_commence_exit so we know TB is guest TB */1195ld r3, HSTATE_KVM_VCORE(r13)1196mfspr r5,SPRN_DEC1197mftb r61198extsw r5,r5119916: add r5,r5,r61200std r5,VCPU_DEC_EXPIRES(r9)12011202/* Increment exit count, poke other threads to exit */1203mr r3, r121204bl kvmhv_commence_exit1205nop1206ld r9, HSTATE_KVM_VCPU(r13)12071208/* Stop others sending VCPU interrupts to this physical CPU */1209li r0, -11210stw r0, VCPU_CPU(r9)1211stw r0, VCPU_THREAD_CPU(r9)12121213/* Save guest CTRL register, set runlatch to 1 if it was clear */1214mfspr r6,SPRN_CTRLF1215stw r6,VCPU_CTRL(r9)1216andi. r0,r6,11217bne 4f1218li r6,11219mtspr SPRN_CTRLT,r612204:1221/*1222* Save the guest PURR/SPURR1223*/1224mfspr r5,SPRN_PURR1225mfspr r6,SPRN_SPURR1226ld r7,VCPU_PURR(r9)1227ld r8,VCPU_SPURR(r9)1228std r5,VCPU_PURR(r9)1229std r6,VCPU_SPURR(r9)1230subf r5,r7,r51231subf r6,r8,r612321233/*1234* Restore host PURR/SPURR and add guest times1235* so that the time in the guest gets accounted.1236*/1237ld r3,HSTATE_PURR(r13)1238ld r4,HSTATE_SPURR(r13)1239add r3,r3,r51240add r4,r4,r61241mtspr SPRN_PURR,r31242mtspr SPRN_SPURR,r412431244BEGIN_FTR_SECTION1245b 8f1246END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)1247/* Save POWER8-specific registers */1248mfspr r5, SPRN_IAMR1249mfspr r6, SPRN_PSPB1250mfspr r7, SPRN_FSCR1251std r5, VCPU_IAMR(r9)1252stw r6, VCPU_PSPB(r9)1253std r7, VCPU_FSCR(r9)1254mfspr r5, SPRN_IC1255mfspr r7, SPRN_TAR1256std r5, VCPU_IC(r9)1257std r7, VCPU_TAR(r9)1258mfspr r8, SPRN_EBBHR1259std r8, VCPU_EBBHR(r9)1260mfspr r5, SPRN_EBBRR1261mfspr r6, SPRN_BESCR1262mfspr r7, SPRN_PID1263mfspr r8, SPRN_WORT1264std r5, VCPU_EBBRR(r9)1265std r6, VCPU_BESCR(r9)1266stw r7, VCPU_GUEST_PID(r9)1267std r8, VCPU_WORT(r9)1268mfspr r5, SPRN_TCSCR1269mfspr r6, SPRN_ACOP1270mfspr r7, SPRN_CSIGR1271mfspr r8, SPRN_TACR1272std r5, VCPU_TCSCR(r9)1273std r6, VCPU_ACOP(r9)1274std r7, VCPU_CSIGR(r9)1275std r8, VCPU_TACR(r9)1276BEGIN_FTR_SECTION1277ld r5, STACK_SLOT_FSCR(r1)1278mtspr SPRN_FSCR, r51279END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)1280/*1281* Restore various registers to 0, where non-zero values1282* set by the guest could disrupt the host.1283*/1284li r0, 01285mtspr SPRN_PSPB, r01286mtspr SPRN_WORT, r01287mtspr SPRN_TCSCR, r01288/* Set MMCRS to 1<<31 to freeze and disable the SPMC counters */1289li r0, 11290sldi r0, r0, 311291mtspr SPRN_MMCRS, r012921293/* Save and restore AMR, IAMR and UAMOR before turning on the MMU */1294ld r8, STACK_SLOT_IAMR(r1)1295mtspr SPRN_IAMR, r8129612978: /* Power7 jumps back in here */1298mfspr r5,SPRN_AMR1299mfspr r6,SPRN_UAMOR1300std r5,VCPU_AMR(r9)1301std r6,VCPU_UAMOR(r9)1302ld r5,STACK_SLOT_AMR(r1)1303ld r6,STACK_SLOT_UAMOR(r1)1304mtspr SPRN_AMR, r51305mtspr SPRN_UAMOR, r613061307/* Switch DSCR back to host value */1308mfspr r8, SPRN_DSCR1309ld r7, HSTATE_DSCR(r13)1310std r8, VCPU_DSCR(r9)1311mtspr SPRN_DSCR, r713121313/* Save non-volatile GPRs */1314std r14, VCPU_GPR(R14)(r9)1315std r15, VCPU_GPR(R15)(r9)1316std r16, VCPU_GPR(R16)(r9)1317std r17, VCPU_GPR(R17)(r9)1318std r18, VCPU_GPR(R18)(r9)1319std r19, VCPU_GPR(R19)(r9)1320std r20, VCPU_GPR(R20)(r9)1321std r21, VCPU_GPR(R21)(r9)1322std r22, VCPU_GPR(R22)(r9)1323std r23, VCPU_GPR(R23)(r9)1324std r24, VCPU_GPR(R24)(r9)1325std r25, VCPU_GPR(R25)(r9)1326std r26, VCPU_GPR(R26)(r9)1327std r27, VCPU_GPR(R27)(r9)1328std r28, VCPU_GPR(R28)(r9)1329std r29, VCPU_GPR(R29)(r9)1330std r30, VCPU_GPR(R30)(r9)1331std r31, VCPU_GPR(R31)(r9)13321333/* Save SPRGs */1334mfspr r3, SPRN_SPRG01335mfspr r4, SPRN_SPRG11336mfspr r5, SPRN_SPRG21337mfspr r6, SPRN_SPRG31338std r3, VCPU_SPRG0(r9)1339std r4, VCPU_SPRG1(r9)1340std r5, VCPU_SPRG2(r9)1341std r6, VCPU_SPRG3(r9)13421343/* save FP state */1344mr r3, r91345bl kvmppc_save_fp13461347#ifdef CONFIG_PPC_TRANSACTIONAL_MEM1348BEGIN_FTR_SECTION1349b 91f1350END_FTR_SECTION_IFCLR(CPU_FTR_TM)1351/*1352* NOTE THAT THIS TRASHES ALL NON-VOLATILE REGISTERS (but not CR)1353*/1354mr r3, r91355ld r4, VCPU_MSR(r3)1356li r5, 0 /* don't preserve non-vol regs */1357bl kvmppc_save_tm_hv1358nop1359ld r9, HSTATE_KVM_VCPU(r13)136091:1361#endif13621363/* Increment yield count if they have a VPA */1364ld r8, VCPU_VPA(r9) /* do they have a VPA? */1365cmpdi r8, 01366beq 25f1367li r4, LPPACA_YIELDCOUNT1368LWZX_BE r3, r8, r41369addi r3, r3, 11370STWX_BE r3, r8, r41371li r3, 11372stb r3, VCPU_VPA_DIRTY(r9)137325:1374/* Save PMU registers if requested */1375/* r8 and cr0.eq are live here */1376mr r3, r91377li r4, 11378beq 21f /* if no VPA, save PMU stuff anyway */1379lbz r4, LPPACA_PMCINUSE(r8)138021: bl kvmhv_save_guest_pmu1381ld r9, HSTATE_KVM_VCPU(r13)13821383/* Restore host values of some registers */1384BEGIN_FTR_SECTION1385ld r5, STACK_SLOT_CIABR(r1)1386ld r6, STACK_SLOT_DAWR0(r1)1387ld r7, STACK_SLOT_DAWRX0(r1)1388mtspr SPRN_CIABR, r51389/*1390* If the DAWR doesn't work, it's ok to write these here as1391* this value should always be zero1392*/1393mtspr SPRN_DAWR0, r61394mtspr SPRN_DAWRX0, r71395END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)13961397/*1398* POWER7/POWER8 guest -> host partition switch code.1399* We don't have to lock against tlbies but we do1400* have to coordinate the hardware threads.1401* Here STACK_SLOT_TRAP(r1) contains the trap number.1402*/1403kvmhv_switch_to_host:1404/* Secondary threads wait for primary to do partition switch */1405ld r5,HSTATE_KVM_VCORE(r13)1406ld r4,VCORE_KVM(r5) /* pointer to struct kvm */1407lbz r3,HSTATE_PTID(r13)1408cmpwi r3,01409beq 15f1410HMT_LOW141113: lbz r3,VCORE_IN_GUEST(r5)1412cmpwi r3,01413bne 13b1414HMT_MEDIUM1415b 16f14161417/* Primary thread waits for all the secondaries to exit guest */141815: lwz r3,VCORE_ENTRY_EXIT(r5)1419rlwinm r0,r3,32-8,0xff1420clrldi r3,r3,561421cmpw r3,r01422bne 15b1423isync14241425/* Did we actually switch to the guest at all? */1426lbz r6, VCORE_IN_GUEST(r5)1427cmpwi r6, 01428beq 19f14291430/* Primary thread switches back to host partition */1431lwz r7,KVM_HOST_LPID(r4)1432ld r6,KVM_HOST_SDR1(r4)1433li r8,LPID_RSVD /* switch to reserved LPID */1434mtspr SPRN_LPID,r81435ptesync1436mtspr SPRN_SDR1,r6 /* switch to host page table */1437mtspr SPRN_LPID,r71438isync14391440BEGIN_FTR_SECTION1441/* DPDES and VTB are shared between threads */1442mfspr r7, SPRN_DPDES1443mfspr r8, SPRN_VTB1444std r7, VCORE_DPDES(r5)1445std r8, VCORE_VTB(r5)1446/* clear DPDES so we don't get guest doorbells in the host */1447li r8, 01448mtspr SPRN_DPDES, r81449END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)14501451/* Subtract timebase offset from timebase */1452ld r8, VCORE_TB_OFFSET_APPL(r5)1453cmpdi r8,01454beq 17f1455li r0, 01456std r0, VCORE_TB_OFFSET_APPL(r5)1457mftb r6 /* current guest timebase */1458subf r8,r8,r61459mtspr SPRN_TBU40,r8 /* update upper 40 bits */1460mftb r7 /* check if lower 24 bits overflowed */1461clrldi r6,r6,401462clrldi r7,r7,401463cmpld r7,r61464bge 17f1465addis r8,r8,0x100 /* if so, increment upper 40 bits */1466mtspr SPRN_TBU40,r81467146817:1469/*1470* If this is an HMI, we called kvmppc_realmode_hmi_handler1471* above, which may or may not have already called1472* kvmppc_subcore_exit_guest. Fortunately, all that1473* kvmppc_subcore_exit_guest does is clear a flag, so calling1474* it again here is benign even if kvmppc_realmode_hmi_handler1475* has already called it.1476*/1477bl kvmppc_subcore_exit_guest1478nop147930: ld r5,HSTATE_KVM_VCORE(r13)1480ld r4,VCORE_KVM(r5) /* pointer to struct kvm */14811482/* Reset PCR */1483ld r0, VCORE_PCR(r5)1484LOAD_REG_IMMEDIATE(r6, PCR_MASK)1485cmpld r0, r61486beq 18f1487mtspr SPRN_PCR, r6148818:1489/* Signal secondary CPUs to continue */1490li r0, 01491stb r0,VCORE_IN_GUEST(r5)149219: lis r8,0x7fff /* MAX_INT@h */1493mtspr SPRN_HDEC,r81494149516: ld r8,KVM_HOST_LPCR(r4)1496mtspr SPRN_LPCR,r81497isync14981499#ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING1500/* Finish timing, if we have a vcpu */1501ld r4, HSTATE_KVM_VCPU(r13)1502cmpdi r4, 01503li r3, 01504beq 2f1505bl kvmhv_accumulate_time15062:1507#endif1508/* Unset guest mode */1509li r0, KVM_GUEST_MODE_NONE1510stb r0, HSTATE_IN_GUEST(r13)15111512lwz r12, STACK_SLOT_TRAP(r1) /* return trap # in r12 */1513ld r0, SFS+PPC_LR_STKOFF(r1)1514addi r1, r1, SFS1515mtlr r01516blr15171518.balign 321519.global kvm_flush_link_stack1520kvm_flush_link_stack:1521/* Save LR into r0 */1522mflr r015231524/* Flush the link stack. On Power8 it's up to 32 entries in size. */1525.rept 321526bl .+41527.endr15281529/* And on Power9 it's up to 64. */1530BEGIN_FTR_SECTION1531.rept 321532bl .+41533.endr1534END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)15351536/* Restore LR */1537mtlr r01538blr15391540kvmppc_guest_external:1541/* External interrupt, first check for host_ipi. If this is1542* set, we know the host wants us out so let's do it now1543*/1544bl CFUNC(kvmppc_read_intr)15451546/*1547* Restore the active volatile registers after returning from1548* a C function.1549*/1550ld r9, HSTATE_KVM_VCPU(r13)1551li r12, BOOK3S_INTERRUPT_EXTERNAL15521553/*1554* kvmppc_read_intr return codes:1555*1556* Exit to host (r3 > 0)1557* 1 An interrupt is pending that needs to be handled by the host1558* Exit guest and return to host by branching to guest_exit_cont1559*1560* 2 Passthrough that needs completion in the host1561* Exit guest and return to host by branching to guest_exit_cont1562* However, we also set r12 to BOOK3S_INTERRUPT_HV_RM_HARD1563* to indicate to the host to complete handling the interrupt1564*1565* Before returning to guest, we check if any CPU is heading out1566* to the host and if so, we head out also. If no CPUs are heading1567* check return values <= 0.1568*1569* Return to guest (r3 <= 0)1570* 0 No external interrupt is pending1571* -1 A guest wakeup IPI (which has now been cleared)1572* In either case, we return to guest to deliver any pending1573* guest interrupts.1574*1575* -2 A PCI passthrough external interrupt was handled1576* (interrupt was delivered directly to guest)1577* Return to guest to deliver any pending guest interrupts.1578*/15791580cmpdi r3, 11581ble 1f15821583/* Return code = 2 */1584li r12, BOOK3S_INTERRUPT_HV_RM_HARD1585stw r12, VCPU_TRAP(r9)1586b guest_exit_cont158715881: /* Return code <= 1 */1589cmpdi r3, 01590bgt guest_exit_cont15911592/* Return code <= 0 */1593maybe_reenter_guest:1594ld r5, HSTATE_KVM_VCORE(r13)1595lwz r0, VCORE_ENTRY_EXIT(r5)1596cmpwi r0, 0x1001597mr r4, r91598blt deliver_guest_interrupt1599b guest_exit_cont16001601/*1602* Check whether an HDSI is an HPTE not found fault or something else.1603* If it is an HPTE not found fault that is due to the guest accessing1604* a page that they have mapped but which we have paged out, then1605* we continue on with the guest exit path. In all other cases,1606* reflect the HDSI to the guest as a DSI.1607*/1608kvmppc_hdsi:1609mfspr r4, SPRN_HDAR1610mfspr r6, SPRN_HDSISR1611/* HPTE not found fault or protection fault? */1612andis. r0, r6, (DSISR_NOHPTE | DSISR_PROTFAULT)@h1613beq 1f /* if not, send it to the guest */1614andi. r0, r11, MSR_DR /* data relocation enabled? */1615beq 3f1616clrrdi r0, r4, 281617PPC_SLBFEE_DOT(R5, R0) /* if so, look up SLB */1618li r0, BOOK3S_INTERRUPT_DATA_SEGMENT1619bne 7f /* if no SLB entry found */16204: std r4, VCPU_FAULT_DAR(r9)1621stw r6, VCPU_FAULT_DSISR(r9)16221623/* Search the hash table. */1624mr r3, r9 /* vcpu pointer */1625li r7, 1 /* data fault */1626bl CFUNC(kvmppc_hpte_hv_fault)1627ld r9, HSTATE_KVM_VCPU(r13)1628ld r10, VCPU_PC(r9)1629ld r11, VCPU_MSR(r9)1630li r12, BOOK3S_INTERRUPT_H_DATA_STORAGE1631cmpdi r3, 0 /* retry the instruction */1632beq 6f1633cmpdi r3, -1 /* handle in kernel mode */1634beq guest_exit_cont1635cmpdi r3, -2 /* MMIO emulation; need instr word */1636beq 2f16371638/* Synthesize a DSI (or DSegI) for the guest */1639ld r4, VCPU_FAULT_DAR(r9)1640mr r6, r316411: li r0, BOOK3S_INTERRUPT_DATA_STORAGE1642mtspr SPRN_DSISR, r616437: mtspr SPRN_DAR, r41644mtspr SPRN_SRR0, r101645mtspr SPRN_SRR1, r111646mr r10, r01647bl kvmppc_msr_interrupt1648fast_interrupt_c_return:16496: ld r7, VCPU_CTR(r9)1650ld r8, VCPU_XER(r9)1651mtctr r71652mtxer r81653mr r4, r91654b fast_guest_return165516563: ld r5, VCPU_KVM(r9) /* not relocated, use VRMA */1657ld r5, KVM_VRMA_SLB_V(r5)1658b 4b16591660/* If this is for emulated MMIO, load the instruction word */16612: li r8, KVM_INST_FETCH_FAILED /* In case lwz faults */16621663/* Set guest mode to 'jump over instruction' so if lwz faults1664* we'll just continue at the next IP. */1665li r0, KVM_GUEST_MODE_SKIP1666stb r0, HSTATE_IN_GUEST(r13)16671668/* Do the access with MSR:DR enabled */1669mfmsr r31670ori r4, r3, MSR_DR /* Enable paging for data */1671mtmsrd r41672lwz r8, 0(r10)1673mtmsrd r316741675/* Store the result */1676std r8, VCPU_LAST_INST(r9)16771678/* Unset guest mode. */1679li r0, KVM_GUEST_MODE_HOST_HV1680stb r0, HSTATE_IN_GUEST(r13)1681b guest_exit_cont16821683/*1684* Similarly for an HISI, reflect it to the guest as an ISI unless1685* it is an HPTE not found fault for a page that we have paged out.1686*/1687kvmppc_hisi:1688andis. r0, r11, SRR1_ISI_NOPT@h1689beq 1f1690andi. r0, r11, MSR_IR /* instruction relocation enabled? */1691beq 3f1692clrrdi r0, r10, 281693PPC_SLBFEE_DOT(R5, R0) /* if so, look up SLB */1694li r0, BOOK3S_INTERRUPT_INST_SEGMENT1695bne 7f /* if no SLB entry found */16964:1697/* Search the hash table. */1698mr r3, r9 /* vcpu pointer */1699mr r4, r101700mr r6, r111701li r7, 0 /* instruction fault */1702bl CFUNC(kvmppc_hpte_hv_fault)1703ld r9, HSTATE_KVM_VCPU(r13)1704ld r10, VCPU_PC(r9)1705ld r11, VCPU_MSR(r9)1706li r12, BOOK3S_INTERRUPT_H_INST_STORAGE1707cmpdi r3, 0 /* retry the instruction */1708beq fast_interrupt_c_return1709cmpdi r3, -1 /* handle in kernel mode */1710beq guest_exit_cont17111712/* Synthesize an ISI (or ISegI) for the guest */1713mr r11, r317141: li r0, BOOK3S_INTERRUPT_INST_STORAGE17157: mtspr SPRN_SRR0, r101716mtspr SPRN_SRR1, r111717mr r10, r01718bl kvmppc_msr_interrupt1719b fast_interrupt_c_return172017213: ld r6, VCPU_KVM(r9) /* not relocated, use VRMA */1722ld r5, KVM_VRMA_SLB_V(r6)1723b 4b17241725/*1726* Try to handle an hcall in real mode.1727* Returns to the guest if we handle it, or continues on up to1728* the kernel if we can't (i.e. if we don't have a handler for1729* it, or if the handler returns H_TOO_HARD).1730*1731* r5 - r8 contain hcall args,1732* r9 = vcpu, r10 = pc, r11 = msr, r12 = trap, r13 = paca1733*/1734hcall_try_real_mode:1735ld r3,VCPU_GPR(R3)(r9)1736andi. r0,r11,MSR_PR1737/* sc 1 from userspace - reflect to guest syscall */1738bne sc_1_fast_return1739clrrdi r3,r3,21740cmpldi r3,hcall_real_table_end - hcall_real_table1741bge guest_exit_cont1742/* See if this hcall is enabled for in-kernel handling */1743ld r4, VCPU_KVM(r9)1744srdi r0, r3, 8 /* r0 = (r3 / 4) >> 6 */1745sldi r0, r0, 3 /* index into kvm->arch.enabled_hcalls[] */1746add r4, r4, r01747ld r0, KVM_ENABLED_HCALLS(r4)1748rlwinm r4, r3, 32-2, 0x3f /* r4 = (r3 / 4) & 0x3f */1749srd r0, r0, r41750andi. r0, r0, 11751beq guest_exit_cont1752/* Get pointer to handler, if any, and call it */1753LOAD_REG_ADDR(r4, hcall_real_table)1754lwax r3,r3,r41755cmpwi r3,01756beq guest_exit_cont1757add r12,r3,r41758mtctr r121759mr r3,r9 /* get vcpu pointer */1760ld r4,VCPU_GPR(R4)(r9)1761bctrl1762cmpdi r3,H_TOO_HARD1763beq hcall_real_fallback1764ld r4,HSTATE_KVM_VCPU(r13)1765std r3,VCPU_GPR(R3)(r4)1766ld r10,VCPU_PC(r4)1767ld r11,VCPU_MSR(r4)1768b fast_guest_return17691770sc_1_fast_return:1771mtspr SPRN_SRR0,r101772mtspr SPRN_SRR1,r111773li r10, BOOK3S_INTERRUPT_SYSCALL1774bl kvmppc_msr_interrupt1775mr r4,r91776b fast_guest_return17771778/* We've attempted a real mode hcall, but it's punted it back1779* to userspace. We need to restore some clobbered volatiles1780* before resuming the pass-it-to-qemu path */1781hcall_real_fallback:1782li r12,BOOK3S_INTERRUPT_SYSCALL1783ld r9, HSTATE_KVM_VCPU(r13)17841785b guest_exit_cont17861787.globl hcall_real_table1788hcall_real_table:1789.long 0 /* 0 - unused */1790.long DOTSYM(kvmppc_h_remove) - hcall_real_table1791.long DOTSYM(kvmppc_h_enter) - hcall_real_table1792.long DOTSYM(kvmppc_h_read) - hcall_real_table1793.long DOTSYM(kvmppc_h_clear_mod) - hcall_real_table1794.long DOTSYM(kvmppc_h_clear_ref) - hcall_real_table1795.long DOTSYM(kvmppc_h_protect) - hcall_real_table1796.long 0 /* 0x1c */1797.long 0 /* 0x20 */1798.long 0 /* 0x24 - H_SET_SPRG0 */1799.long DOTSYM(kvmppc_h_set_dabr) - hcall_real_table1800.long DOTSYM(kvmppc_rm_h_page_init) - hcall_real_table1801.long 0 /* 0x30 */1802.long 0 /* 0x34 */1803.long 0 /* 0x38 */1804.long 0 /* 0x3c */1805.long 0 /* 0x40 */1806.long 0 /* 0x44 */1807.long 0 /* 0x48 */1808.long 0 /* 0x4c */1809.long 0 /* 0x50 */1810.long 0 /* 0x54 */1811.long 0 /* 0x58 */1812.long 0 /* 0x5c */1813.long 0 /* 0x60 */1814#ifdef CONFIG_KVM_XICS1815.long DOTSYM(xics_rm_h_eoi) - hcall_real_table1816.long DOTSYM(xics_rm_h_cppr) - hcall_real_table1817.long DOTSYM(xics_rm_h_ipi) - hcall_real_table1818.long 0 /* 0x70 - H_IPOLL */1819.long DOTSYM(xics_rm_h_xirr) - hcall_real_table1820#else1821.long 0 /* 0x64 - H_EOI */1822.long 0 /* 0x68 - H_CPPR */1823.long 0 /* 0x6c - H_IPI */1824.long 0 /* 0x70 - H_IPOLL */1825.long 0 /* 0x74 - H_XIRR */1826#endif1827.long 0 /* 0x78 */1828.long 0 /* 0x7c */1829.long 0 /* 0x80 */1830.long 0 /* 0x84 */1831.long 0 /* 0x88 */1832.long 0 /* 0x8c */1833.long 0 /* 0x90 */1834.long 0 /* 0x94 */1835.long 0 /* 0x98 */1836.long 0 /* 0x9c */1837.long 0 /* 0xa0 */1838.long 0 /* 0xa4 */1839.long 0 /* 0xa8 */1840.long 0 /* 0xac */1841.long 0 /* 0xb0 */1842.long 0 /* 0xb4 */1843.long 0 /* 0xb8 */1844.long 0 /* 0xbc */1845.long 0 /* 0xc0 */1846.long 0 /* 0xc4 */1847.long 0 /* 0xc8 */1848.long 0 /* 0xcc */1849.long 0 /* 0xd0 */1850.long 0 /* 0xd4 */1851.long 0 /* 0xd8 */1852.long 0 /* 0xdc */1853.long DOTSYM(kvmppc_h_cede) - hcall_real_table1854.long DOTSYM(kvmppc_rm_h_confer) - hcall_real_table1855.long 0 /* 0xe8 */1856.long 0 /* 0xec */1857.long 0 /* 0xf0 */1858.long 0 /* 0xf4 */1859.long 0 /* 0xf8 */1860.long 0 /* 0xfc */1861.long 0 /* 0x100 */1862.long 0 /* 0x104 */1863.long 0 /* 0x108 */1864.long 0 /* 0x10c */1865.long 0 /* 0x110 */1866.long 0 /* 0x114 */1867.long 0 /* 0x118 */1868.long 0 /* 0x11c */1869.long 0 /* 0x120 */1870.long DOTSYM(kvmppc_h_bulk_remove) - hcall_real_table1871.long 0 /* 0x128 */1872.long 0 /* 0x12c */1873.long 0 /* 0x130 */1874.long DOTSYM(kvmppc_h_set_xdabr) - hcall_real_table1875.long 0 /* 0x138 */1876.long 0 /* 0x13c */1877.long 0 /* 0x140 */1878.long 0 /* 0x144 */1879.long 0 /* 0x148 */1880.long 0 /* 0x14c */1881.long 0 /* 0x150 */1882.long 0 /* 0x154 */1883.long 0 /* 0x158 */1884.long 0 /* 0x15c */1885.long 0 /* 0x160 */1886.long 0 /* 0x164 */1887.long 0 /* 0x168 */1888.long 0 /* 0x16c */1889.long 0 /* 0x170 */1890.long 0 /* 0x174 */1891.long 0 /* 0x178 */1892.long 0 /* 0x17c */1893.long 0 /* 0x180 */1894.long 0 /* 0x184 */1895.long 0 /* 0x188 */1896.long 0 /* 0x18c */1897.long 0 /* 0x190 */1898.long 0 /* 0x194 */1899.long 0 /* 0x198 */1900.long 0 /* 0x19c */1901.long 0 /* 0x1a0 */1902.long 0 /* 0x1a4 */1903.long 0 /* 0x1a8 */1904.long 0 /* 0x1ac */1905.long 0 /* 0x1b0 */1906.long 0 /* 0x1b4 */1907.long 0 /* 0x1b8 */1908.long 0 /* 0x1bc */1909.long 0 /* 0x1c0 */1910.long 0 /* 0x1c4 */1911.long 0 /* 0x1c8 */1912.long 0 /* 0x1cc */1913.long 0 /* 0x1d0 */1914.long 0 /* 0x1d4 */1915.long 0 /* 0x1d8 */1916.long 0 /* 0x1dc */1917.long 0 /* 0x1e0 */1918.long 0 /* 0x1e4 */1919.long 0 /* 0x1e8 */1920.long 0 /* 0x1ec */1921.long 0 /* 0x1f0 */1922.long 0 /* 0x1f4 */1923.long 0 /* 0x1f8 */1924.long 0 /* 0x1fc */1925.long 0 /* 0x200 */1926.long 0 /* 0x204 */1927.long 0 /* 0x208 */1928.long 0 /* 0x20c */1929.long 0 /* 0x210 */1930.long 0 /* 0x214 */1931.long 0 /* 0x218 */1932.long 0 /* 0x21c */1933.long 0 /* 0x220 */1934.long 0 /* 0x224 */1935.long 0 /* 0x228 */1936.long 0 /* 0x22c */1937.long 0 /* 0x230 */1938.long 0 /* 0x234 */1939.long 0 /* 0x238 */1940.long 0 /* 0x23c */1941.long 0 /* 0x240 */1942.long 0 /* 0x244 */1943.long 0 /* 0x248 */1944.long 0 /* 0x24c */1945.long 0 /* 0x250 */1946.long 0 /* 0x254 */1947.long 0 /* 0x258 */1948.long 0 /* 0x25c */1949.long 0 /* 0x260 */1950.long 0 /* 0x264 */1951.long 0 /* 0x268 */1952.long 0 /* 0x26c */1953.long 0 /* 0x270 */1954.long 0 /* 0x274 */1955.long 0 /* 0x278 */1956.long 0 /* 0x27c */1957.long 0 /* 0x280 */1958.long 0 /* 0x284 */1959.long 0 /* 0x288 */1960.long 0 /* 0x28c */1961.long 0 /* 0x290 */1962.long 0 /* 0x294 */1963.long 0 /* 0x298 */1964.long 0 /* 0x29c */1965.long 0 /* 0x2a0 */1966.long 0 /* 0x2a4 */1967.long 0 /* 0x2a8 */1968.long 0 /* 0x2ac */1969.long 0 /* 0x2b0 */1970.long 0 /* 0x2b4 */1971.long 0 /* 0x2b8 */1972.long 0 /* 0x2bc */1973.long 0 /* 0x2c0 */1974.long 0 /* 0x2c4 */1975.long 0 /* 0x2c8 */1976.long 0 /* 0x2cc */1977.long 0 /* 0x2d0 */1978.long 0 /* 0x2d4 */1979.long 0 /* 0x2d8 */1980.long 0 /* 0x2dc */1981.long 0 /* 0x2e0 */1982.long 0 /* 0x2e4 */1983.long 0 /* 0x2e8 */1984.long 0 /* 0x2ec */1985.long 0 /* 0x2f0 */1986.long 0 /* 0x2f4 */1987.long 0 /* 0x2f8 */1988#ifdef CONFIG_KVM_XICS1989.long DOTSYM(xics_rm_h_xirr_x) - hcall_real_table1990#else1991.long 0 /* 0x2fc - H_XIRR_X*/1992#endif1993.long DOTSYM(kvmppc_rm_h_random) - hcall_real_table1994.globl hcall_real_table_end1995hcall_real_table_end:19961997_GLOBAL_TOC(kvmppc_h_set_xdabr)1998EXPORT_SYMBOL_GPL(kvmppc_h_set_xdabr)1999andi. r0, r5, DABRX_USER | DABRX_KERNEL2000beq 6f2001li r0, DABRX_USER | DABRX_KERNEL | DABRX_BTI2002andc. r0, r5, r02003beq 3f20046: li r3, H_PARAMETER2005blr20062007_GLOBAL_TOC(kvmppc_h_set_dabr)2008EXPORT_SYMBOL_GPL(kvmppc_h_set_dabr)2009li r5, DABRX_USER | DABRX_KERNEL20103:2011BEGIN_FTR_SECTION2012b 2f2013END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)2014std r4,VCPU_DABR(r3)2015stw r5, VCPU_DABRX(r3)2016mtspr SPRN_DABRX, r52017/* Work around P7 bug where DABR can get corrupted on mtspr */20181: mtspr SPRN_DABR,r42019mfspr r5, SPRN_DABR2020cmpd r4, r52021bne 1b2022isync2023li r3,02024blr202520262:2027LOAD_REG_ADDR(r11, dawr_force_enable)2028lbz r11, 0(r11)2029cmpdi r11, 02030bne 3f2031li r3, H_HARDWARE2032blr20333:2034/* Emulate H_SET_DABR/X on P8 for the sake of compat mode guests */2035rlwimi r5, r4, 5, DAWRX_DR | DAWRX_DW2036rlwimi r5, r4, 2, DAWRX_WT2037clrrdi r4, r4, 32038std r4, VCPU_DAWR0(r3)2039std r5, VCPU_DAWRX0(r3)2040/*2041* If came in through the real mode hcall handler then it is necessary2042* to write the registers since the return path won't. Otherwise it is2043* sufficient to store then in the vcpu struct as they will be loaded2044* next time the vcpu is run.2045*/2046mfmsr r62047andi. r6, r6, MSR_DR /* in real mode? */2048bne 4f2049mtspr SPRN_DAWR0, r42050mtspr SPRN_DAWRX0, r520514: li r3, 02052blr20532054_GLOBAL(kvmppc_h_cede) /* r3 = vcpu pointer, r11 = msr, r13 = paca */2055ori r11,r11,MSR_EE2056std r11,VCPU_MSR(r3)2057li r0,12058stb r0,VCPU_CEDED(r3)2059sync /* order setting ceded vs. testing prodded */2060lbz r5,VCPU_PRODDED(r3)2061cmpwi r5,02062bne kvm_cede_prodded2063li r12,0 /* set trap to 0 to say hcall is handled */2064stw r12,VCPU_TRAP(r3)2065li r0,H_SUCCESS2066std r0,VCPU_GPR(R3)(r3)20672068/*2069* Set our bit in the bitmask of napping threads unless all the2070* other threads are already napping, in which case we send this2071* up to the host.2072*/2073ld r5,HSTATE_KVM_VCORE(r13)2074lbz r6,HSTATE_PTID(r13)2075lwz r8,VCORE_ENTRY_EXIT(r5)2076clrldi r8,r8,562077li r0,12078sld r0,r0,r62079addi r6,r5,VCORE_NAPPING_THREADS208031: lwarx r4,0,r62081or r4,r4,r02082cmpw r4,r82083beq kvm_cede_exit2084stwcx. r4,0,r62085bne 31b2086/* order napping_threads update vs testing entry_exit_map */2087isync2088li r0,NAPPING_CEDE2089stb r0,HSTATE_NAPPING(r13)2090lwz r7,VCORE_ENTRY_EXIT(r5)2091cmpwi r7,0x1002092bge 33f /* another thread already exiting */20932094/*2095* Although not specifically required by the architecture, POWER72096* preserves the following registers in nap mode, even if an SMT mode2097* switch occurs: SLB entries, PURR, SPURR, AMOR, UAMOR, AMR, SPRG0-3,2098* DAR, DSISR, DABR, DABRX, DSCR, PMCx, MMCRx, SIAR, SDAR.2099*/2100/* Save non-volatile GPRs */2101std r14, VCPU_GPR(R14)(r3)2102std r15, VCPU_GPR(R15)(r3)2103std r16, VCPU_GPR(R16)(r3)2104std r17, VCPU_GPR(R17)(r3)2105std r18, VCPU_GPR(R18)(r3)2106std r19, VCPU_GPR(R19)(r3)2107std r20, VCPU_GPR(R20)(r3)2108std r21, VCPU_GPR(R21)(r3)2109std r22, VCPU_GPR(R22)(r3)2110std r23, VCPU_GPR(R23)(r3)2111std r24, VCPU_GPR(R24)(r3)2112std r25, VCPU_GPR(R25)(r3)2113std r26, VCPU_GPR(R26)(r3)2114std r27, VCPU_GPR(R27)(r3)2115std r28, VCPU_GPR(R28)(r3)2116std r29, VCPU_GPR(R29)(r3)2117std r30, VCPU_GPR(R30)(r3)2118std r31, VCPU_GPR(R31)(r3)21192120/* save FP state */2121bl kvmppc_save_fp21222123#ifdef CONFIG_PPC_TRANSACTIONAL_MEM2124BEGIN_FTR_SECTION2125b 91f2126END_FTR_SECTION_IFCLR(CPU_FTR_TM)2127/*2128* NOTE THAT THIS TRASHES ALL NON-VOLATILE REGISTERS (but not CR)2129*/2130ld r3, HSTATE_KVM_VCPU(r13)2131ld r4, VCPU_MSR(r3)2132li r5, 0 /* don't preserve non-vol regs */2133bl kvmppc_save_tm_hv2134nop213591:2136#endif21372138/*2139* Set DEC to the smaller of DEC and HDEC, so that we wake2140* no later than the end of our timeslice (HDEC interrupts2141* don't wake us from nap).2142*/2143mfspr r3, SPRN_DEC2144mfspr r4, SPRN_HDEC2145mftb r52146extsw r3, r32147extsw r4, r42148cmpd r3, r42149ble 67f2150mtspr SPRN_DEC, r4215167:2152/* save expiry time of guest decrementer */2153add r3, r3, r52154ld r4, HSTATE_KVM_VCPU(r13)2155std r3, VCPU_DEC_EXPIRES(r4)21562157#ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING2158ld r4, HSTATE_KVM_VCPU(r13)2159addi r3, r4, VCPU_TB_CEDE2160bl kvmhv_accumulate_time2161#endif21622163lis r3, LPCR_PECEDP@h /* Do wake on privileged doorbell */21642165/* Go back to host stack */2166ld r1, HSTATE_HOST_R1(r13)21672168/*2169* Take a nap until a decrementer or external or doobell interrupt2170* occurs, with PECE1 and PECE0 set in LPCR.2171* On POWER8, set PECEDH, and if we are ceding, also set PECEDP.2172* Also clear the runlatch bit before napping.2173*/2174kvm_do_nap:2175li r0,02176mtspr SPRN_CTRLT, r021772178li r0,12179stb r0,HSTATE_HWTHREAD_REQ(r13)2180mfspr r5,SPRN_LPCR2181ori r5,r5,LPCR_PECE0 | LPCR_PECE12182BEGIN_FTR_SECTION2183ori r5, r5, LPCR_PECEDH2184rlwimi r5, r3, 0, LPCR_PECEDP2185END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)21862187kvm_nap_sequence: /* desired LPCR value in r5 */2188li r3, PNV_THREAD_NAP2189mtspr SPRN_LPCR,r52190isync21912192bl isa206_idle_insn_mayloss21932194li r0,12195mtspr SPRN_CTRLT, r021962197mtspr SPRN_SRR1, r321982199li r0, 02200stb r0, PACA_FTRACE_ENABLED(r13)22012202li r0, KVM_HWTHREAD_IN_KVM2203stb r0, HSTATE_HWTHREAD_STATE(r13)22042205lbz r0, HSTATE_NAPPING(r13)2206cmpwi r0, NAPPING_CEDE2207beq kvm_end_cede2208cmpwi r0, NAPPING_NOVCPU2209beq kvm_novcpu_wakeup2210cmpwi r0, NAPPING_UNSPLIT2211beq kvm_unsplit_wakeup2212twi 31,0,0 /* Nap state must not be zero */2213221433: mr r4, r32215li r3, 02216li r12, 02217b 34f22182219kvm_end_cede:2220/* Woken by external or decrementer interrupt */22212222/* get vcpu pointer */2223ld r4, HSTATE_KVM_VCPU(r13)22242225#ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING2226addi r3, r4, VCPU_TB_RMINTR2227bl kvmhv_accumulate_time2228#endif22292230#ifdef CONFIG_PPC_TRANSACTIONAL_MEM2231BEGIN_FTR_SECTION2232b 91f2233END_FTR_SECTION_IFCLR(CPU_FTR_TM)2234/*2235* NOTE THAT THIS TRASHES ALL NON-VOLATILE REGISTERS (but not CR)2236*/2237mr r3, r42238ld r4, VCPU_MSR(r3)2239li r5, 0 /* don't preserve non-vol regs */2240bl kvmppc_restore_tm_hv2241nop2242ld r4, HSTATE_KVM_VCPU(r13)224391:2244#endif22452246/* load up FP state */2247bl kvmppc_load_fp22482249/* Restore guest decrementer */2250ld r3, VCPU_DEC_EXPIRES(r4)2251mftb r72252subf r3, r7, r32253mtspr SPRN_DEC, r322542255/* Load NV GPRS */2256ld r14, VCPU_GPR(R14)(r4)2257ld r15, VCPU_GPR(R15)(r4)2258ld r16, VCPU_GPR(R16)(r4)2259ld r17, VCPU_GPR(R17)(r4)2260ld r18, VCPU_GPR(R18)(r4)2261ld r19, VCPU_GPR(R19)(r4)2262ld r20, VCPU_GPR(R20)(r4)2263ld r21, VCPU_GPR(R21)(r4)2264ld r22, VCPU_GPR(R22)(r4)2265ld r23, VCPU_GPR(R23)(r4)2266ld r24, VCPU_GPR(R24)(r4)2267ld r25, VCPU_GPR(R25)(r4)2268ld r26, VCPU_GPR(R26)(r4)2269ld r27, VCPU_GPR(R27)(r4)2270ld r28, VCPU_GPR(R28)(r4)2271ld r29, VCPU_GPR(R29)(r4)2272ld r30, VCPU_GPR(R30)(r4)2273ld r31, VCPU_GPR(R31)(r4)22742275/* Check the wake reason in SRR1 to see why we got here */2276bl kvmppc_check_wake_reason22772278/*2279* Restore volatile registers since we could have called a2280* C routine in kvmppc_check_wake_reason2281* r4 = VCPU2282* r3 tells us whether we need to return to host or not2283* WARNING: it gets checked further down:2284* should not modify r3 until this check is done.2285*/2286ld r4, HSTATE_KVM_VCPU(r13)22872288/* clear our bit in vcore->napping_threads */228934: ld r5,HSTATE_KVM_VCORE(r13)2290lbz r7,HSTATE_PTID(r13)2291li r0,12292sld r0,r0,r72293addi r6,r5,VCORE_NAPPING_THREADS229432: lwarx r7,0,r62295andc r7,r7,r02296stwcx. r7,0,r62297bne 32b2298li r0,02299stb r0,HSTATE_NAPPING(r13)23002301/* See if the wake reason saved in r3 means we need to exit */2302stw r12, VCPU_TRAP(r4)2303mr r9, r42304cmpdi r3, 02305bgt guest_exit_cont2306b maybe_reenter_guest23072308/* cede when already previously prodded case */2309kvm_cede_prodded:2310li r0,02311stb r0,VCPU_PRODDED(r3)2312sync /* order testing prodded vs. clearing ceded */2313stb r0,VCPU_CEDED(r3)2314li r3,H_SUCCESS2315blr23162317/* we've ceded but we want to give control to the host */2318kvm_cede_exit:2319ld r9, HSTATE_KVM_VCPU(r13)2320b guest_exit_cont23212322/* Try to do machine check recovery in real mode */2323machine_check_realmode:2324mr r3, r9 /* get vcpu pointer */2325bl kvmppc_realmode_machine_check2326nop2327/* all machine checks go to virtual mode for further handling */2328ld r9, HSTATE_KVM_VCPU(r13)2329li r12, BOOK3S_INTERRUPT_MACHINE_CHECK2330b guest_exit_cont23312332/*2333* Call C code to handle a HMI in real mode.2334* Only the primary thread does the call, secondary threads are handled2335* by calling hmi_exception_realmode() after kvmppc_hv_entry returns.2336* r9 points to the vcpu on entry2337*/2338hmi_realmode:2339lbz r0, HSTATE_PTID(r13)2340cmpwi r0, 02341bne guest_exit_cont2342bl CFUNC(kvmppc_realmode_hmi_handler)2343ld r9, HSTATE_KVM_VCPU(r13)2344li r12, BOOK3S_INTERRUPT_HMI2345b guest_exit_cont23462347/*2348* Check the reason we woke from nap, and take appropriate action.2349* Returns (in r3):2350* 0 if nothing needs to be done2351* 1 if something happened that needs to be handled by the host2352* -1 if there was a guest wakeup (IPI or msgsnd)2353* -2 if we handled a PCI passthrough interrupt (returned by2354* kvmppc_read_intr only)2355*2356* Also sets r12 to the interrupt vector for any interrupt that needs2357* to be handled now by the host (0x500 for external interrupt), or zero.2358* Modifies all volatile registers (since it may call a C function).2359* This routine calls kvmppc_read_intr, a C function, if an external2360* interrupt is pending.2361*/2362SYM_FUNC_START_LOCAL(kvmppc_check_wake_reason)2363mfspr r6, SPRN_SRR12364BEGIN_FTR_SECTION2365rlwinm r6, r6, 45-31, 0xf /* extract wake reason field (P8) */2366FTR_SECTION_ELSE2367rlwinm r6, r6, 45-31, 0xe /* P7 wake reason field is 3 bits */2368ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_207S)2369cmpwi r6, 8 /* was it an external interrupt? */2370beq 7f /* if so, see what it was */2371li r3, 02372li r12, 02373cmpwi r6, 6 /* was it the decrementer? */2374beq 0f2375BEGIN_FTR_SECTION2376cmpwi r6, 5 /* privileged doorbell? */2377beq 0f2378cmpwi r6, 3 /* hypervisor doorbell? */2379beq 3f2380END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)2381cmpwi r6, 0xa /* Hypervisor maintenance ? */2382beq 4f2383li r3, 1 /* anything else, return 1 */23840: blr23852386/* hypervisor doorbell */23873: li r12, BOOK3S_INTERRUPT_H_DOORBELL23882389/*2390* Clear the doorbell as we will invoke the handler2391* explicitly in the guest exit path.2392*/2393lis r6, (PPC_DBELL_SERVER << (63-36))@h2394PPC_MSGCLR(6)2395/* see if it's a host IPI */2396li r3, 12397lbz r0, HSTATE_HOST_IPI(r13)2398cmpwi r0, 02399bnelr2400/* if not, return -1 */2401li r3, -12402blr24032404/* Woken up due to Hypervisor maintenance interrupt */24054: li r12, BOOK3S_INTERRUPT_HMI2406li r3, 12407blr24082409/* external interrupt - create a stack frame so we can call C */24107: mflr r02411std r0, PPC_LR_STKOFF(r1)2412stdu r1, -PPC_MIN_STKFRM(r1)2413bl CFUNC(kvmppc_read_intr)2414nop2415li r12, BOOK3S_INTERRUPT_EXTERNAL2416cmpdi r3, 12417ble 1f24182419/*2420* Return code of 2 means PCI passthrough interrupt, but2421* we need to return back to host to complete handling the2422* interrupt. Trap reason is expected in r12 by guest2423* exit code.2424*/2425li r12, BOOK3S_INTERRUPT_HV_RM_HARD24261:2427ld r0, PPC_MIN_STKFRM+PPC_LR_STKOFF(r1)2428addi r1, r1, PPC_MIN_STKFRM2429mtlr r02430blr2431SYM_FUNC_END(kvmppc_check_wake_reason)24322433/*2434* Save away FP, VMX and VSX registers.2435* r3 = vcpu pointer2436* N.B. r30 and r31 are volatile across this function,2437* thus it is not callable from C.2438*/2439SYM_FUNC_START_LOCAL(kvmppc_save_fp)2440mflr r302441mr r31,r32442mfmsr r52443ori r8,r5,MSR_FP2444#ifdef CONFIG_ALTIVEC2445BEGIN_FTR_SECTION2446oris r8,r8,MSR_VEC@h2447END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)2448#endif2449#ifdef CONFIG_VSX2450BEGIN_FTR_SECTION2451oris r8,r8,MSR_VSX@h2452END_FTR_SECTION_IFSET(CPU_FTR_VSX)2453#endif2454mtmsrd r82455addi r3,r3,VCPU_FPRS2456bl store_fp_state2457#ifdef CONFIG_ALTIVEC2458BEGIN_FTR_SECTION2459addi r3,r31,VCPU_VRS2460bl store_vr_state2461END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)2462#endif2463mfspr r6,SPRN_VRSAVE2464stw r6,VCPU_VRSAVE(r31)2465mtlr r302466blr2467SYM_FUNC_END(kvmppc_save_fp)24682469/*2470* Load up FP, VMX and VSX registers2471* r4 = vcpu pointer2472* N.B. r30 and r31 are volatile across this function,2473* thus it is not callable from C.2474*/2475SYM_FUNC_START_LOCAL(kvmppc_load_fp)2476mflr r302477mr r31,r42478mfmsr r92479ori r8,r9,MSR_FP2480#ifdef CONFIG_ALTIVEC2481BEGIN_FTR_SECTION2482oris r8,r8,MSR_VEC@h2483END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)2484#endif2485#ifdef CONFIG_VSX2486BEGIN_FTR_SECTION2487oris r8,r8,MSR_VSX@h2488END_FTR_SECTION_IFSET(CPU_FTR_VSX)2489#endif2490mtmsrd r82491addi r3,r4,VCPU_FPRS2492bl load_fp_state2493#ifdef CONFIG_ALTIVEC2494BEGIN_FTR_SECTION2495addi r3,r31,VCPU_VRS2496bl load_vr_state2497END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)2498#endif2499lwz r7,VCPU_VRSAVE(r31)2500mtspr SPRN_VRSAVE,r72501mtlr r302502mr r4,r312503blr2504SYM_FUNC_END(kvmppc_load_fp)25052506#ifdef CONFIG_PPC_TRANSACTIONAL_MEM2507/*2508* Save transactional state and TM-related registers.2509* Called with r3 pointing to the vcpu struct and r4 containing2510* the guest MSR value.2511* r5 is non-zero iff non-volatile register state needs to be maintained.2512* If r5 == 0, this can modify all checkpointed registers, but2513* restores r1 and r2 before exit.2514*/2515_GLOBAL_TOC(kvmppc_save_tm_hv)2516EXPORT_SYMBOL_GPL(kvmppc_save_tm_hv)2517/* See if we need to handle fake suspend mode */2518BEGIN_FTR_SECTION2519b __kvmppc_save_tm2520END_FTR_SECTION_IFCLR(CPU_FTR_P9_TM_HV_ASSIST)25212522lbz r0, HSTATE_FAKE_SUSPEND(r13) /* Were we fake suspended? */2523cmpwi r0, 02524beq __kvmppc_save_tm25252526/* The following code handles the fake_suspend = 1 case */2527mflr r02528std r0, PPC_LR_STKOFF(r1)2529stdu r1, -TM_FRAME_SIZE(r1)25302531/* Turn on TM. */2532mfmsr r82533li r0, 12534rldimi r8, r0, MSR_TM_LG, 63-MSR_TM_LG2535mtmsrd r825362537rldicl. r8, r8, 64 - MSR_TS_S_LG, 62 /* Did we actually hrfid? */2538beq 4f2539BEGIN_FTR_SECTION2540bl pnv_power9_force_smt4_catch2541END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_XER_SO_BUG)2542nop25432544/*2545* It's possible that treclaim. may modify registers, if we have lost2546* track of fake-suspend state in the guest due to it using rfscv.2547* Save and restore registers in case this occurs.2548*/2549mfspr r3, SPRN_DSCR2550mfspr r4, SPRN_XER2551mfspr r5, SPRN_AMR2552/* SPRN_TAR would need to be saved here if the kernel ever used it */2553mfcr r122554SAVE_NVGPRS(r1)2555SAVE_GPR(2, r1)2556SAVE_GPR(3, r1)2557SAVE_GPR(4, r1)2558SAVE_GPR(5, r1)2559stw r12, 8(r1)2560std r1, HSTATE_HOST_R1(r13)25612562/* We have to treclaim here because that's the only way to do S->N */2563li r3, TM_CAUSE_KVM_RESCHED2564TRECLAIM(R3)25652566GET_PACA(r13)2567ld r1, HSTATE_HOST_R1(r13)2568REST_GPR(2, r1)2569REST_GPR(3, r1)2570REST_GPR(4, r1)2571REST_GPR(5, r1)2572lwz r12, 8(r1)2573REST_NVGPRS(r1)2574mtspr SPRN_DSCR, r32575mtspr SPRN_XER, r42576mtspr SPRN_AMR, r52577mtcr r122578HMT_MEDIUM25792580/*2581* We were in fake suspend, so we are not going to save the2582* register state as the guest checkpointed state (since2583* we already have it), therefore we can now use any volatile GPR.2584* In fact treclaim in fake suspend state doesn't modify2585* any registers.2586*/25872588BEGIN_FTR_SECTION2589bl pnv_power9_force_smt4_release2590END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_XER_SO_BUG)2591nop259225934:2594mfspr r3, SPRN_PSSCR2595/* PSSCR_FAKE_SUSPEND is a write-only bit, but clear it anyway */2596li r0, PSSCR_FAKE_SUSPEND2597andc r3, r3, r02598mtspr SPRN_PSSCR, r325992600/* Don't save TEXASR, use value from last exit in real suspend state */2601ld r9, HSTATE_KVM_VCPU(r13)2602mfspr r5, SPRN_TFHAR2603mfspr r6, SPRN_TFIAR2604std r5, VCPU_TFHAR(r9)2605std r6, VCPU_TFIAR(r9)26062607addi r1, r1, TM_FRAME_SIZE2608ld r0, PPC_LR_STKOFF(r1)2609mtlr r02610blr26112612/*2613* Restore transactional state and TM-related registers.2614* Called with r3 pointing to the vcpu struct2615* and r4 containing the guest MSR value.2616* r5 is non-zero iff non-volatile register state needs to be maintained.2617* This potentially modifies all checkpointed registers.2618* It restores r1 and r2 from the PACA.2619*/2620_GLOBAL_TOC(kvmppc_restore_tm_hv)2621EXPORT_SYMBOL_GPL(kvmppc_restore_tm_hv)2622/*2623* If we are doing TM emulation for the guest on a POWER9 DD2,2624* then we don't actually do a trechkpt -- we either set up2625* fake-suspend mode, or emulate a TM rollback.2626*/2627BEGIN_FTR_SECTION2628b __kvmppc_restore_tm2629END_FTR_SECTION_IFCLR(CPU_FTR_P9_TM_HV_ASSIST)2630mflr r02631std r0, PPC_LR_STKOFF(r1)26322633li r0, 02634stb r0, HSTATE_FAKE_SUSPEND(r13)26352636/* Turn on TM so we can restore TM SPRs */2637mfmsr r52638li r0, 12639rldimi r5, r0, MSR_TM_LG, 63-MSR_TM_LG2640mtmsrd r526412642/*2643* The user may change these outside of a transaction, so they must2644* always be context switched.2645*/2646ld r5, VCPU_TFHAR(r3)2647ld r6, VCPU_TFIAR(r3)2648ld r7, VCPU_TEXASR(r3)2649mtspr SPRN_TFHAR, r52650mtspr SPRN_TFIAR, r62651mtspr SPRN_TEXASR, r726522653rldicl. r5, r4, 64 - MSR_TS_S_LG, 622654beqlr /* TM not active in guest */26552656/* Make sure the failure summary is set */2657oris r7, r7, (TEXASR_FS)@h2658mtspr SPRN_TEXASR, r726592660cmpwi r5, 1 /* check for suspended state */2661bgt 10f2662stb r5, HSTATE_FAKE_SUSPEND(r13)2663b 9f /* and return */266410: stdu r1, -PPC_MIN_STKFRM(r1)2665/* guest is in transactional state, so simulate rollback */2666bl kvmhv_emulate_tm_rollback2667nop2668addi r1, r1, PPC_MIN_STKFRM26699: ld r0, PPC_LR_STKOFF(r1)2670mtlr r02671blr2672#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */26732674/*2675* We come here if we get any exception or interrupt while we are2676* executing host real mode code while in guest MMU context.2677* r12 is (CR << 32) | vector2678* r13 points to our PACA2679* r12 is saved in HSTATE_SCRATCH0(r13)2680* r9 is saved in HSTATE_SCRATCH2(r13)2681* r13 is saved in HSPRG12682* cfar is saved in HSTATE_CFAR(r13)2683* ppr is saved in HSTATE_PPR(r13)2684*/2685kvmppc_bad_host_intr:2686/*2687* Switch to the emergency stack, but start half-way down in2688* case we were already on it.2689*/2690mr r9, r12691std r1, PACAR1(r13)2692ld r1, PACAEMERGSP(r13)2693subi r1, r1, THREAD_SIZE/2 + INT_FRAME_SIZE2694std r9, 0(r1)2695std r0, GPR0(r1)2696std r9, GPR1(r1)2697std r2, GPR2(r1)2698SAVE_GPRS(3, 8, r1)2699srdi r0, r12, 322700clrldi r12, r12, 322701std r0, _CCR(r1)2702std r12, _TRAP(r1)2703andi. r0, r12, 22704beq 1f2705mfspr r3, SPRN_HSRR02706mfspr r4, SPRN_HSRR12707mfspr r5, SPRN_HDAR2708mfspr r6, SPRN_HDSISR2709b 2f27101: mfspr r3, SPRN_SRR02711mfspr r4, SPRN_SRR12712mfspr r5, SPRN_DAR2713mfspr r6, SPRN_DSISR27142: std r3, _NIP(r1)2715std r4, _MSR(r1)2716std r5, _DAR(r1)2717std r6, _DSISR(r1)2718ld r9, HSTATE_SCRATCH2(r13)2719ld r12, HSTATE_SCRATCH0(r13)2720GET_SCRATCH0(r0)2721SAVE_GPRS(9, 12, r1)2722std r0, GPR13(r1)2723SAVE_NVGPRS(r1)2724ld r5, HSTATE_CFAR(r13)2725std r5, ORIG_GPR3(r1)2726mflr r32727mfctr r42728mfxer r52729lbz r6, PACAIRQSOFTMASK(r13)2730std r3, _LINK(r1)2731std r4, _CTR(r1)2732std r5, _XER(r1)2733std r6, SOFTE(r1)2734LOAD_PACA_TOC()2735LOAD_REG_IMMEDIATE(3, STACK_FRAME_REGS_MARKER)2736std r3, STACK_INT_FRAME_MARKER(r1)27372738/*2739* XXX On POWER7 and POWER8, we just spin here since we don't2740* know what the other threads are doing (and we don't want to2741* coordinate with them) - but at least we now have register state2742* in memory that we might be able to look at from another CPU.2743*/2744b .27452746/*2747* This mimics the MSR transition on IRQ delivery. The new guest MSR is taken2748* from VCPU_INTR_MSR and is modified based on the required TM state changes.2749* r11 has the guest MSR value (in/out)2750* r9 has a vcpu pointer (in)2751* r0 is used as a scratch register2752*/2753SYM_FUNC_START_LOCAL(kvmppc_msr_interrupt)2754rldicl r0, r11, 64 - MSR_TS_S_LG, 622755cmpwi r0, 2 /* Check if we are in transactional state.. */2756ld r11, VCPU_INTR_MSR(r9)2757bne 1f2758/* ... if transactional, change to suspended */2759li r0, 127601: rldimi r11, r0, MSR_TS_S_LG, 63 - MSR_TS_T_LG2761blr2762SYM_FUNC_END(kvmppc_msr_interrupt)27632764/*2765* void kvmhv_load_guest_pmu(struct kvm_vcpu *vcpu)2766*2767* Load up guest PMU state. R3 points to the vcpu struct.2768*/2769SYM_FUNC_START_LOCAL(kvmhv_load_guest_pmu)2770mr r4, r32771mflr r02772li r3, 12773sldi r3, r3, 31 /* MMCR0_FC (freeze counters) bit */2774mtspr SPRN_MMCR0, r3 /* freeze all counters, disable ints */2775isync2776BEGIN_FTR_SECTION2777ld r3, VCPU_MMCR(r4)2778andi. r5, r3, MMCR0_PMAO_SYNC | MMCR0_PMAO2779cmpwi r5, MMCR0_PMAO2780beql kvmppc_fix_pmao2781END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG)2782lwz r3, VCPU_PMC(r4) /* always load up guest PMU registers */2783lwz r5, VCPU_PMC + 4(r4) /* to prevent information leak */2784lwz r6, VCPU_PMC + 8(r4)2785lwz r7, VCPU_PMC + 12(r4)2786lwz r8, VCPU_PMC + 16(r4)2787lwz r9, VCPU_PMC + 20(r4)2788mtspr SPRN_PMC1, r32789mtspr SPRN_PMC2, r52790mtspr SPRN_PMC3, r62791mtspr SPRN_PMC4, r72792mtspr SPRN_PMC5, r82793mtspr SPRN_PMC6, r92794ld r3, VCPU_MMCR(r4)2795ld r5, VCPU_MMCR + 8(r4)2796ld r6, VCPU_MMCRA(r4)2797ld r7, VCPU_SIAR(r4)2798ld r8, VCPU_SDAR(r4)2799mtspr SPRN_MMCR1, r52800mtspr SPRN_MMCRA, r62801mtspr SPRN_SIAR, r72802mtspr SPRN_SDAR, r82803BEGIN_FTR_SECTION2804ld r5, VCPU_MMCR + 16(r4)2805ld r6, VCPU_SIER(r4)2806mtspr SPRN_MMCR2, r52807mtspr SPRN_SIER, r62808lwz r7, VCPU_PMC + 24(r4)2809lwz r8, VCPU_PMC + 28(r4)2810ld r9, VCPU_MMCRS(r4)2811mtspr SPRN_SPMC1, r72812mtspr SPRN_SPMC2, r82813mtspr SPRN_MMCRS, r92814END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)2815mtspr SPRN_MMCR0, r32816isync2817mtlr r02818blr2819SYM_FUNC_END(kvmhv_load_guest_pmu)28202821/*2822* void kvmhv_load_host_pmu(void)2823*2824* Reload host PMU state saved in the PACA by kvmhv_save_host_pmu.2825*/2826SYM_FUNC_START_LOCAL(kvmhv_load_host_pmu)2827mflr r02828lbz r4, PACA_PMCINUSE(r13) /* is the host using the PMU? */2829cmpwi r4, 02830beq 23f /* skip if not */2831BEGIN_FTR_SECTION2832ld r3, HSTATE_MMCR0(r13)2833andi. r4, r3, MMCR0_PMAO_SYNC | MMCR0_PMAO2834cmpwi r4, MMCR0_PMAO2835beql kvmppc_fix_pmao2836END_FTR_SECTION_IFSET(CPU_FTR_PMAO_BUG)2837lwz r3, HSTATE_PMC1(r13)2838lwz r4, HSTATE_PMC2(r13)2839lwz r5, HSTATE_PMC3(r13)2840lwz r6, HSTATE_PMC4(r13)2841lwz r8, HSTATE_PMC5(r13)2842lwz r9, HSTATE_PMC6(r13)2843mtspr SPRN_PMC1, r32844mtspr SPRN_PMC2, r42845mtspr SPRN_PMC3, r52846mtspr SPRN_PMC4, r62847mtspr SPRN_PMC5, r82848mtspr SPRN_PMC6, r92849ld r3, HSTATE_MMCR0(r13)2850ld r4, HSTATE_MMCR1(r13)2851ld r5, HSTATE_MMCRA(r13)2852ld r6, HSTATE_SIAR(r13)2853ld r7, HSTATE_SDAR(r13)2854mtspr SPRN_MMCR1, r42855mtspr SPRN_MMCRA, r52856mtspr SPRN_SIAR, r62857mtspr SPRN_SDAR, r72858BEGIN_FTR_SECTION2859ld r8, HSTATE_MMCR2(r13)2860ld r9, HSTATE_SIER(r13)2861mtspr SPRN_MMCR2, r82862mtspr SPRN_SIER, r92863END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)2864mtspr SPRN_MMCR0, r32865isync2866mtlr r0286723: blr2868SYM_FUNC_END(kvmhv_load_host_pmu)28692870/*2871* void kvmhv_save_guest_pmu(struct kvm_vcpu *vcpu, bool pmu_in_use)2872*2873* Save guest PMU state into the vcpu struct.2874* r3 = vcpu, r4 = full save flag (PMU in use flag set in VPA)2875*/2876SYM_FUNC_START_LOCAL(kvmhv_save_guest_pmu)2877mr r9, r32878mr r8, r42879BEGIN_FTR_SECTION2880/*2881* POWER8 seems to have a hardware bug where setting2882* MMCR0[PMAE] along with MMCR0[PMC1CE] and/or MMCR0[PMCjCE]2883* when some counters are already negative doesn't seem2884* to cause a performance monitor alert (and hence interrupt).2885* The effect of this is that when saving the PMU state,2886* if there is no PMU alert pending when we read MMCR02887* before freezing the counters, but one becomes pending2888* before we read the counters, we lose it.2889* To work around this, we need a way to freeze the counters2890* before reading MMCR0. Normally, freezing the counters2891* is done by writing MMCR0 (to set MMCR0[FC]) which2892* unavoidably writes MMCR0[PMA0] as well. On POWER8,2893* we can also freeze the counters using MMCR2, by writing2894* 1s to all the counter freeze condition bits (there are2895* 9 bits each for 6 counters).2896*/2897li r3, -1 /* set all freeze bits */2898clrrdi r3, r3, 102899mfspr r10, SPRN_MMCR22900mtspr SPRN_MMCR2, r32901isync2902END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)2903li r3, 12904sldi r3, r3, 31 /* MMCR0_FC (freeze counters) bit */2905mfspr r4, SPRN_MMCR0 /* save MMCR0 */2906mtspr SPRN_MMCR0, r3 /* freeze all counters, disable ints */2907mfspr r6, SPRN_MMCRA2908/* Clear MMCRA in order to disable SDAR updates */2909li r7, 02910mtspr SPRN_MMCRA, r72911isync2912cmpwi r8, 0 /* did they ask for PMU stuff to be saved? */2913bne 21f2914std r3, VCPU_MMCR(r9) /* if not, set saved MMCR0 to FC */2915b 22f291621: mfspr r5, SPRN_MMCR12917mfspr r7, SPRN_SIAR2918mfspr r8, SPRN_SDAR2919std r4, VCPU_MMCR(r9)2920std r5, VCPU_MMCR + 8(r9)2921std r6, VCPU_MMCRA(r9)2922BEGIN_FTR_SECTION2923std r10, VCPU_MMCR + 16(r9)2924END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)2925std r7, VCPU_SIAR(r9)2926std r8, VCPU_SDAR(r9)2927mfspr r3, SPRN_PMC12928mfspr r4, SPRN_PMC22929mfspr r5, SPRN_PMC32930mfspr r6, SPRN_PMC42931mfspr r7, SPRN_PMC52932mfspr r8, SPRN_PMC62933stw r3, VCPU_PMC(r9)2934stw r4, VCPU_PMC + 4(r9)2935stw r5, VCPU_PMC + 8(r9)2936stw r6, VCPU_PMC + 12(r9)2937stw r7, VCPU_PMC + 16(r9)2938stw r8, VCPU_PMC + 20(r9)2939BEGIN_FTR_SECTION2940mfspr r5, SPRN_SIER2941std r5, VCPU_SIER(r9)2942mfspr r6, SPRN_SPMC12943mfspr r7, SPRN_SPMC22944mfspr r8, SPRN_MMCRS2945stw r6, VCPU_PMC + 24(r9)2946stw r7, VCPU_PMC + 28(r9)2947std r8, VCPU_MMCRS(r9)2948lis r4, 0x80002949mtspr SPRN_MMCRS, r42950END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)295122: blr2952SYM_FUNC_END(kvmhv_save_guest_pmu)29532954/*2955* This works around a hardware bug on POWER8E processors, where2956* writing a 1 to the MMCR0[PMAO] bit doesn't generate a2957* performance monitor interrupt. Instead, when we need to have2958* an interrupt pending, we have to arrange for a counter to overflow.2959*/2960kvmppc_fix_pmao:2961li r3, 02962mtspr SPRN_MMCR2, r32963lis r3, (MMCR0_PMXE | MMCR0_FCECE)@h2964ori r3, r3, MMCR0_PMCjCE | MMCR0_C56RUN2965mtspr SPRN_MMCR0, r32966lis r3, 0x7fff2967ori r3, r3, 0xffff2968mtspr SPRN_PMC6, r32969isync2970blr29712972#ifdef CONFIG_KVM_BOOK3S_HV_P8_TIMING2973/*2974* Start timing an activity2975* r3 = pointer to time accumulation struct, r4 = vcpu2976*/2977kvmhv_start_timing:2978ld r5, HSTATE_KVM_VCORE(r13)2979ld r6, VCORE_TB_OFFSET_APPL(r5)2980mftb r52981subf r5, r6, r5 /* subtract current timebase offset */2982std r3, VCPU_CUR_ACTIVITY(r4)2983std r5, VCPU_ACTIVITY_START(r4)2984blr29852986/*2987* Accumulate time to one activity and start another.2988* r3 = pointer to new time accumulation struct, r4 = vcpu2989*/2990kvmhv_accumulate_time:2991ld r5, HSTATE_KVM_VCORE(r13)2992ld r8, VCORE_TB_OFFSET_APPL(r5)2993ld r5, VCPU_CUR_ACTIVITY(r4)2994ld r6, VCPU_ACTIVITY_START(r4)2995std r3, VCPU_CUR_ACTIVITY(r4)2996mftb r72997subf r7, r8, r7 /* subtract current timebase offset */2998std r7, VCPU_ACTIVITY_START(r4)2999cmpdi r5, 03000beqlr3001subf r3, r6, r73002ld r8, TAS_SEQCOUNT(r5)3003cmpdi r8, 03004addi r8, r8, 13005std r8, TAS_SEQCOUNT(r5)3006lwsync3007ld r7, TAS_TOTAL(r5)3008add r7, r7, r33009std r7, TAS_TOTAL(r5)3010ld r6, TAS_MIN(r5)3011ld r7, TAS_MAX(r5)3012beq 3f3013cmpd r3, r63014bge 1f30153: std r3, TAS_MIN(r5)30161: cmpd r3, r73017ble 2f3018std r3, TAS_MAX(r5)30192: lwsync3020addi r8, r8, 13021std r8, TAS_SEQCOUNT(r5)3022blr3023#endif302430253026