~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/powerpc/kvm/book3s_rmhandlers.S

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-only */
  2 /*
  3  *
  4  * Copyright SUSE Linux Products GmbH 2009
  5  *
  6  * Authors: Alexander Graf <agraf@suse.de>
  7  */
  8 
  9 #include <asm/ppc_asm.h>
 10 #include <asm/kvm_asm.h>
 11 #include <asm/reg.h>
 12 #include <asm/mmu.h>
 13 #include <asm/page.h>
 14 #include <asm/asm-offsets.h>
 15 #include <asm/asm-compat.h>
 16 
 17 #ifdef CONFIG_PPC_BOOK3S_64
 18 #include <asm/exception-64s.h>
 19 #endif
 20 
 21 /*****************************************************************************
 22  *                                                                           *
 23  *        Real Mode handlers that need to be in low physical memory          *
 24  *                                                                           *
 25  ****************************************************************************/
 26 
 27 #if defined(CONFIG_PPC_BOOK3S_64)
 28 
 29 #ifdef CONFIG_PPC64_ELF_ABI_V2
 30 #define FUNC(name)              name
 31 #else
 32 #define FUNC(name)              GLUE(.,name)
 33 #endif
 34 
 35 #elif defined(CONFIG_PPC_BOOK3S_32)
 36 
 37 #define FUNC(name)              name
 38 
 39 #define RFI_TO_KERNEL   rfi
 40 #define RFI_TO_GUEST    rfi
 41 
 42 .macro INTERRUPT_TRAMPOLINE intno
 43 
 44 .global kvmppc_trampoline_\intno
 45 kvmppc_trampoline_\intno:
 46 
 47         mtspr   SPRN_SPRG_SCRATCH0, r13         /* Save r13 */
 48 
 49         /*
 50          * First thing to do is to find out if we're coming
 51          * from a KVM guest or a Linux process.
 52          *
 53          * To distinguish, we check a magic byte in the PACA/current
 54          */
 55         mfspr   r13, SPRN_SPRG_THREAD
 56         lwz     r13, THREAD_KVM_SVCPU(r13)
 57         /* PPC32 can have a NULL pointer - let's check for that */
 58         mtspr   SPRN_SPRG_SCRATCH1, r12         /* Save r12 */
 59         mfcr    r12
 60         cmpwi   r13, 0
 61         bne     1f
 62 2:      mtcr    r12
 63         mfspr   r12, SPRN_SPRG_SCRATCH1
 64         mfspr   r13, SPRN_SPRG_SCRATCH0         /* r13 = original r13 */
 65         b       kvmppc_resume_\intno            /* Get back original handler */
 66 
 67 1:      tophys(r13, r13)
 68         stw     r12, HSTATE_SCRATCH1(r13)
 69         mfspr   r12, SPRN_SPRG_SCRATCH1
 70         stw     r12, HSTATE_SCRATCH0(r13)
 71         lbz     r12, HSTATE_IN_GUEST(r13)
 72         cmpwi   r12, KVM_GUEST_MODE_NONE
 73         bne     ..kvmppc_handler_hasmagic_\intno
 74         /* No KVM guest? Then jump back to the Linux handler! */
 75         lwz     r12, HSTATE_SCRATCH1(r13)
 76         b       2b
 77 
 78         /* Now we know we're handling a KVM guest */
 79 ..kvmppc_handler_hasmagic_\intno:
 80 
 81         /* Should we just skip the faulting instruction? */
 82         cmpwi   r12, KVM_GUEST_MODE_SKIP
 83         beq     kvmppc_handler_skip_ins
 84 
 85         /* Let's store which interrupt we're handling */
 86         li      r12, \intno
 87 
 88         /* Jump into the SLB exit code that goes to the highmem handler */
 89         b       kvmppc_handler_trampoline_exit
 90 
 91 .endm
 92 
 93 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_SYSTEM_RESET
 94 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_MACHINE_CHECK
 95 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_DATA_STORAGE
 96 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_INST_STORAGE
 97 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_EXTERNAL
 98 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_ALIGNMENT
 99 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_PROGRAM
100 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_FP_UNAVAIL
101 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_DECREMENTER
102 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_SYSCALL
103 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_TRACE
104 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_PERFMON
105 INTERRUPT_TRAMPOLINE    BOOK3S_INTERRUPT_ALTIVEC
106 
107 /*
108  * Bring us back to the faulting code, but skip the
109  * faulting instruction.
110  *
111  * This is a generic exit path from the interrupt
112  * trampolines above.
113  *
114  * Input Registers:
115  *
116  * R12            = free
117  * R13            = Shadow VCPU (PACA)
118  * HSTATE.SCRATCH0 = guest R12
119  * HSTATE.SCRATCH1 = guest CR
120  * SPRG_SCRATCH0  = guest R13
121  *
122  */
123 kvmppc_handler_skip_ins:
124 
125         /* Patch the IP to the next instruction */
126         /* Note that prefixed instructions are disabled in PR KVM for now */
127         mfsrr0  r12
128         addi    r12, r12, 4
129         mtsrr0  r12
130 
131         /* Clean up all state */
132         lwz     r12, HSTATE_SCRATCH1(r13)
133         mtcr    r12
134         PPC_LL  r12, HSTATE_SCRATCH0(r13)
135         GET_SCRATCH0(r13)
136 
137         /* And get back into the code */
138         RFI_TO_KERNEL
139 #endif
140 
141 /*
142  * Call kvmppc_handler_trampoline_enter in real mode
143  *
144  * On entry, r4 contains the guest shadow MSR
145  * MSR.EE has to be 0 when calling this function
146  */
147 _GLOBAL_TOC(kvmppc_entry_trampoline)
148         mfmsr   r5
149         LOAD_REG_ADDR(r7, kvmppc_handler_trampoline_enter)
150         toreal(r7)
151 
152         li      r6, MSR_IR | MSR_DR
153         andc    r6, r5, r6      /* Clear DR and IR in MSR value */
154         /*
155          * Set EE in HOST_MSR so that it's enabled when we get into our
156          * C exit handler function.
157          */
158         ori     r5, r5, MSR_EE
159         mtsrr0  r7
160         mtsrr1  r6
161         RFI_TO_KERNEL
162 
163 #include "book3s_segment.S"

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php