/* SPDX-License-Identifier: GPL-2.0-only */1#include <linux/export.h>2#include <asm/asm-offsets.h>3#include <asm/cache.h>4#include <asm/code-patching-asm.h>5#include <asm/exception-64s.h>6#include <asm/kvm_asm.h>7#include <asm/kvm_book3s_asm.h>8#include <asm/mmu.h>9#include <asm/ppc_asm.h>10#include <asm/ptrace.h>11#include <asm/reg.h>12#include <asm/ultravisor-api.h>1314/*15* These are branched to from interrupt handlers in exception-64s.S which set16* IKVM_REAL or IKVM_VIRT, if HSTATE_IN_GUEST was found to be non-zero.17*/1819/*20* This is a hcall, so register convention is as21* Documentation/arch/powerpc/papr_hcalls.rst.22*23* This may also be a syscall from PR-KVM userspace that is to be24* reflected to the PR guest kernel, so registers may be set up for25* a system call rather than hcall. We don't currently clobber26* anything here, but the 0xc00 handler has already clobbered CTR27* and CR0, so PR-KVM can not support a guest kernel that preserves28* those registers across its system calls.29*30* The state of registers is as kvmppc_interrupt, except CFAR is not31* saved, R13 is not in SCRATCH0, and R10 does not contain the trap.32*/33.global kvmppc_hcall34.balign IFETCH_ALIGN_BYTES35kvmppc_hcall:36#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE37lbz r10,HSTATE_IN_GUEST(r13)38cmpwi r10,KVM_GUEST_MODE_HV_P939beq kvmppc_p9_exit_hcall40#endif41ld r10,PACA_EXGEN+EX_R13(r13)42SET_SCRATCH0(r10)43li r10,0xc0044/* Now we look like kvmppc_interrupt */45li r11,PACA_EXGEN46b .Lgot_save_area4748/*49* KVM interrupt entry occurs after GEN_INT_ENTRY runs, and follows that50* call convention:51*52* guest R9-R13, CTR, CFAR, PPR saved in PACA EX_xxx save area53* guest (H)DAR, (H)DSISR are also in the save area for relevant interrupts54* guest R13 also saved in SCRATCH055* R13 = PACA56* R11 = (H)SRR057* R12 = (H)SRR158* R9 = guest CR59* PPR is set to medium60*61* With the addition for KVM:62* R10 = trap vector63*/64.global kvmppc_interrupt65.balign IFETCH_ALIGN_BYTES66kvmppc_interrupt:67#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE68std r10,HSTATE_SCRATCH0(r13)69lbz r10,HSTATE_IN_GUEST(r13)70cmpwi r10,KVM_GUEST_MODE_HV_P971beq kvmppc_p9_exit_interrupt72ld r10,HSTATE_SCRATCH0(r13)73#endif74li r11,PACA_EXGEN75cmpdi r10,0x20076bgt+ .Lgot_save_area77li r11,PACA_EXMC78beq .Lgot_save_area79li r11,PACA_EXNMI80.Lgot_save_area:81add r11,r11,r1382BEGIN_FTR_SECTION83ld r12,EX_CFAR(r11)84std r12,HSTATE_CFAR(r13)85END_FTR_SECTION_IFSET(CPU_FTR_CFAR)86ld r12,EX_CTR(r11)87mtctr r1288BEGIN_FTR_SECTION89ld r12,EX_PPR(r11)90std r12,HSTATE_PPR(r13)91END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)92ld r12,EX_R12(r11)93std r12,HSTATE_SCRATCH0(r13)94sldi r12,r9,3295or r12,r12,r1096ld r9,EX_R9(r11)97ld r10,EX_R10(r11)98ld r11,EX_R11(r11)99100/*101* Hcalls and other interrupts come here after normalising register102* contents and save locations:103*104* R12 = (guest CR << 32) | interrupt vector105* R13 = PACA106* guest R12 saved in shadow HSTATE_SCRATCH0107* guest R13 saved in SPRN_SCRATCH0108*/109std r9,HSTATE_SCRATCH2(r13)110lbz r9,HSTATE_IN_GUEST(r13)111cmpwi r9,KVM_GUEST_MODE_SKIP112beq- .Lmaybe_skip113.Lno_skip:114#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE115#ifdef CONFIG_KVM_BOOK3S_PR_POSSIBLE116cmpwi r9,KVM_GUEST_MODE_GUEST117beq kvmppc_interrupt_pr118#endif119b kvmppc_interrupt_hv120#else121b kvmppc_interrupt_pr122#endif123124/*125* "Skip" interrupts are part of a trick KVM uses a with hash guests to load126* the faulting instruction in guest memory from the hypervisor without127* walking page tables.128*129* When the guest takes a fault that requires the hypervisor to load the130* instruction (e.g., MMIO emulation), KVM is running in real-mode with HV=1131* and the guest MMU context loaded. It sets KVM_GUEST_MODE_SKIP, and sets132* MSR[DR]=1 while leaving MSR[IR]=0, so it continues to fetch HV instructions133* but loads and stores will access the guest context. This is used to load134* the faulting instruction using the faulting guest effective address.135*136* However the guest context may not be able to translate, or it may cause a137* machine check or other issue, which results in a fault in the host138* (even with KVM-HV).139*140* These faults come here because KVM_GUEST_MODE_SKIP was set, so if they141* are (or are likely) caused by that load, the instruction is skipped by142* just returning with the PC advanced +4, where it is noticed the load did143* not execute and it goes to the slow path which walks the page tables to144* read guest memory.145*/146.Lmaybe_skip:147cmpwi r12,BOOK3S_INTERRUPT_MACHINE_CHECK148beq 1f149cmpwi r12,BOOK3S_INTERRUPT_DATA_STORAGE150beq 1f151cmpwi r12,BOOK3S_INTERRUPT_DATA_SEGMENT152beq 1f153#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE154/* HSRR interrupts get 2 added to interrupt number */155cmpwi r12,BOOK3S_INTERRUPT_H_DATA_STORAGE | 0x2156beq 2f157#endif158b .Lno_skip1591: mfspr r9,SPRN_SRR0160addi r9,r9,4161mtspr SPRN_SRR0,r9162ld r12,HSTATE_SCRATCH0(r13)163ld r9,HSTATE_SCRATCH2(r13)164GET_SCRATCH0(r13)165RFI_TO_KERNEL166#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE1672: mfspr r9,SPRN_HSRR0168addi r9,r9,4169mtspr SPRN_HSRR0,r9170ld r12,HSTATE_SCRATCH0(r13)171ld r9,HSTATE_SCRATCH2(r13)172GET_SCRATCH0(r13)173HRFI_TO_KERNEL174#endif175176#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE177178/* Stack frame offsets for kvmppc_p9_enter_guest */179#define SFS (144 + STACK_FRAME_MIN_SIZE)180#define STACK_SLOT_NVGPRS (SFS - 144) /* 18 gprs */181182/*183* void kvmppc_p9_enter_guest(struct vcpu *vcpu);184*185* Enter the guest on a ISAv3.0 or later system.186*/187.balign IFETCH_ALIGN_BYTES188_GLOBAL(kvmppc_p9_enter_guest)189EXPORT_SYMBOL_GPL(kvmppc_p9_enter_guest)190mflr r0191std r0,PPC_LR_STKOFF(r1)192stdu r1,-SFS(r1)193194std r1,HSTATE_HOST_R1(r13)195196mfcr r4197stw r4,SFS+8(r1)198199reg = 14200.rept 18201std reg,STACK_SLOT_NVGPRS + ((reg - 14) * 8)(r1)202reg = reg + 1203.endr204205ld r4,VCPU_LR(r3)206mtlr r4207ld r4,VCPU_CTR(r3)208mtctr r4209ld r4,VCPU_XER(r3)210mtspr SPRN_XER,r4211212ld r1,VCPU_CR(r3)213214BEGIN_FTR_SECTION215ld r4,VCPU_CFAR(r3)216mtspr SPRN_CFAR,r4217END_FTR_SECTION_IFSET(CPU_FTR_CFAR)218BEGIN_FTR_SECTION219ld r4,VCPU_PPR(r3)220mtspr SPRN_PPR,r4221END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)222223reg = 4224.rept 28225ld reg,__VCPU_GPR(reg)(r3)226reg = reg + 1227.endr228229ld r4,VCPU_KVM(r3)230lbz r4,KVM_SECURE_GUEST(r4)231cmpdi r4,0232ld r4,VCPU_GPR(R4)(r3)233bne .Lret_to_ultra234235mtcr r1236237ld r0,VCPU_GPR(R0)(r3)238ld r1,VCPU_GPR(R1)(r3)239ld r2,VCPU_GPR(R2)(r3)240ld r3,VCPU_GPR(R3)(r3)241242HRFI_TO_GUEST243b .244245/*246* Use UV_RETURN ultracall to return control back to the Ultravisor247* after processing an hypercall or interrupt that was forwarded248* (a.k.a. reflected) to the Hypervisor.249*250* All registers have already been reloaded except the ucall requires:251* R0 = hcall result252* R2 = SRR1, so UV can detect a synthesized interrupt (if any)253* R3 = UV_RETURN254*/255.Lret_to_ultra:256mtcr r1257ld r1,VCPU_GPR(R1)(r3)258259ld r0,VCPU_GPR(R3)(r3)260mfspr r2,SPRN_SRR1261LOAD_REG_IMMEDIATE(r3, UV_RETURN)262sc 2263264/*265* kvmppc_p9_exit_hcall and kvmppc_p9_exit_interrupt are branched to from266* above if the interrupt was taken for a guest that was entered via267* kvmppc_p9_enter_guest().268*269* The exit code recovers the host stack and vcpu pointer, saves all guest GPRs270* and CR, LR, XER as well as guest MSR and NIA into the VCPU, then re-271* establishes the host stack and registers to return from the272* kvmppc_p9_enter_guest() function, which saves CTR and other guest registers273* (SPRs and FP, VEC, etc).274*/275.balign IFETCH_ALIGN_BYTES276kvmppc_p9_exit_hcall:277mfspr r11,SPRN_SRR0278mfspr r12,SPRN_SRR1279li r10,0xc00280std r10,HSTATE_SCRATCH0(r13)281282.balign IFETCH_ALIGN_BYTES283kvmppc_p9_exit_interrupt:284/*285* If set to KVM_GUEST_MODE_HV_P9 but we're still in the286* hypervisor, that means we can't return from the entry stack.287*/288rldicl. r10,r12,64-MSR_HV_LG,63289bne- kvmppc_p9_bad_interrupt290291std r1,HSTATE_SCRATCH1(r13)292std r3,HSTATE_SCRATCH2(r13)293ld r1,HSTATE_HOST_R1(r13)294ld r3,HSTATE_KVM_VCPU(r13)295296std r9,VCPU_CR(r3)2972981:299std r11,VCPU_PC(r3)300std r12,VCPU_MSR(r3)301302reg = 14303.rept 18304std reg,__VCPU_GPR(reg)(r3)305reg = reg + 1306.endr307308/* r1, r3, r9-r13 are saved to vcpu by C code */309std r0,VCPU_GPR(R0)(r3)310std r2,VCPU_GPR(R2)(r3)311reg = 4312.rept 5313std reg,__VCPU_GPR(reg)(r3)314reg = reg + 1315.endr316317LOAD_PACA_TOC()318319mflr r4320std r4,VCPU_LR(r3)321mfspr r4,SPRN_XER322std r4,VCPU_XER(r3)323324reg = 14325.rept 18326ld reg,STACK_SLOT_NVGPRS + ((reg - 14) * 8)(r1)327reg = reg + 1328.endr329330lwz r4,SFS+8(r1)331mtcr r4332333/*334* Flush the link stack here, before executing the first blr on the335* way out of the guest.336*337* The link stack won't match coming out of the guest anyway so the338* only cost is the flush itself. The call clobbers r0.339*/3401: nop341patch_site 1b patch__call_kvm_flush_link_stack_p9342343addi r1,r1,SFS344ld r0,PPC_LR_STKOFF(r1)345mtlr r0346blr347348/*349* Took an interrupt somewhere right before HRFID to guest, so registers are350* in a bad way. Return things hopefully enough to run host virtual code and351* run the Linux interrupt handler (SRESET or MCE) to print something useful.352*353* We could be really clever and save all host registers in known locations354* before setting HSTATE_IN_GUEST, then restoring them all here, and setting355* return address to a fixup that sets them up again. But that's a lot of356* effort for a small bit of code. Lots of other things to do first.357*/358kvmppc_p9_bad_interrupt:359BEGIN_MMU_FTR_SECTION360/*361* Hash host doesn't try to recover MMU (requires host SLB reload)362*/363b .364END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX)365/*366* Clean up guest registers to give host a chance to run.367*/368li r10,0369mtspr SPRN_AMR,r10370mtspr SPRN_IAMR,r10371mtspr SPRN_CIABR,r10372mtspr SPRN_DAWRX0,r10373BEGIN_FTR_SECTION374mtspr SPRN_DAWRX1,r10375END_FTR_SECTION_IFSET(CPU_FTR_DAWR1)376377/*378* Switch to host MMU mode (don't have the real host PID but we aren't379* going back to userspace).380*/381hwsync382isync383384mtspr SPRN_PID,r10385386ld r10, HSTATE_KVM_VCPU(r13)387ld r10, VCPU_KVM(r10)388lwz r10, KVM_HOST_LPID(r10)389mtspr SPRN_LPID,r10390391ld r10, HSTATE_KVM_VCPU(r13)392ld r10, VCPU_KVM(r10)393ld r10, KVM_HOST_LPCR(r10)394mtspr SPRN_LPCR,r10395396isync397398/*399* Set GUEST_MODE_NONE so the handler won't branch to KVM, and clear400* MSR_RI in r12 ([H]SRR1) so the handler won't try to return.401*/402li r10,KVM_GUEST_MODE_NONE403stb r10,HSTATE_IN_GUEST(r13)404li r10,MSR_RI405andc r12,r12,r10406407/*408* Go back to interrupt handler. MCE and SRESET have their specific409* PACA save area so they should be used directly. They set up their410* own stack. The other handlers all use EXGEN. They will use the411* guest r1 if it looks like a kernel stack, so just load the412* emergency stack and go to program check for all other interrupts.413*/414ld r10,HSTATE_SCRATCH0(r13)415cmpwi r10,BOOK3S_INTERRUPT_MACHINE_CHECK416beq .Lcall_machine_check_common417418cmpwi r10,BOOK3S_INTERRUPT_SYSTEM_RESET419beq .Lcall_system_reset_common420421b .422423.Lcall_machine_check_common:424b machine_check_common425426.Lcall_system_reset_common:427b system_reset_common428#endif429430431