Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  *
0004  * Copyright SUSE Linux Products GmbH 2009
0005  *
0006  * Authors: Alexander Graf <agraf@suse.de>
0007  */
0008 
0009 #include <asm/asm-compat.h>
0010 #include <asm/feature-fixups.h>
0011 
0012 #define SHADOW_SLB_ENTRY_LEN    0x10
0013 #define OFFSET_ESID(x)      (SHADOW_SLB_ENTRY_LEN * x)
0014 #define OFFSET_VSID(x)      ((SHADOW_SLB_ENTRY_LEN * x) + 8)
0015 
0016 /******************************************************************************
0017  *                                                                            *
0018  *                               Entry code                                   *
0019  *                                                                            *
0020  *****************************************************************************/
0021 
0022 .macro LOAD_GUEST_SEGMENTS
0023 
0024     /* Required state:
0025      *
0026      * MSR = ~IR|DR
0027      * R13 = PACA
0028      * R1 = host R1
0029      * R2 = host R2
0030      * R3 = shadow vcpu
0031      * all other volatile GPRS = free except R4, R6
0032      * SVCPU[CR]  = guest CR
0033      * SVCPU[XER] = guest XER
0034      * SVCPU[CTR] = guest CTR
0035      * SVCPU[LR]  = guest LR
0036      */
0037 
0038 BEGIN_FW_FTR_SECTION
0039 
0040     /* Declare SLB shadow as 0 entries big */
0041 
0042     ld  r11, PACA_SLBSHADOWPTR(r13)
0043     li  r8, 0
0044     stb r8, 3(r11)
0045 
0046 END_FW_FTR_SECTION_IFSET(FW_FEATURE_LPAR)
0047 
0048     /* Flush SLB */
0049 
0050     li  r10, 0
0051     slbmte  r10, r10
0052     slbia
0053 
0054     /* Fill SLB with our shadow */
0055 
0056     lbz r12, SVCPU_SLB_MAX(r3)
0057     mulli   r12, r12, 16
0058     addi    r12, r12, SVCPU_SLB
0059     add r12, r12, r3
0060 
0061     /* for (r11 = kvm_slb; r11 < kvm_slb + kvm_slb_size; r11+=slb_entry) */
0062     li  r11, SVCPU_SLB
0063     add r11, r11, r3
0064 
0065 slb_loop_enter:
0066 
0067     ld  r10, 0(r11)
0068 
0069     andis.  r9, r10, SLB_ESID_V@h
0070     beq slb_loop_enter_skip
0071 
0072     ld  r9, 8(r11)
0073     slbmte  r9, r10
0074 
0075 slb_loop_enter_skip:
0076     addi    r11, r11, 16
0077     cmpd    cr0, r11, r12
0078     blt slb_loop_enter
0079 
0080 slb_do_enter:
0081 
0082 .endm
0083 
0084 /******************************************************************************
0085  *                                                                            *
0086  *                               Exit code                                    *
0087  *                                                                            *
0088  *****************************************************************************/
0089 
0090 .macro LOAD_HOST_SEGMENTS
0091 
0092     /* Register usage at this point:
0093      *
0094      * R1         = host R1
0095      * R2         = host R2
0096      * R12        = exit handler id
0097      * R13        = shadow vcpu - SHADOW_VCPU_OFF [=PACA on PPC64]
0098      * SVCPU.*    = guest *
0099      * SVCPU[CR]  = guest CR
0100      * SVCPU[XER] = guest XER
0101      * SVCPU[CTR] = guest CTR
0102      * SVCPU[LR]  = guest LR
0103      *
0104      */
0105 
0106     /* Remove all SLB entries that are in use. */
0107 
0108     li  r0, 0
0109     slbmte  r0, r0
0110     slbia
0111 
0112     /* Restore bolted entries from the shadow */
0113 
0114     ld  r11, PACA_SLBSHADOWPTR(r13)
0115 
0116 BEGIN_FW_FTR_SECTION
0117 
0118     /* Declare SLB shadow as SLB_NUM_BOLTED entries big */
0119 
0120     li  r8, SLB_NUM_BOLTED
0121     stb r8, 3(r11)
0122 
0123 END_FW_FTR_SECTION_IFSET(FW_FEATURE_LPAR)
0124 
0125     /* Manually load all entries from shadow SLB */
0126 
0127     li  r8, SLBSHADOW_SAVEAREA
0128     li  r7, SLBSHADOW_SAVEAREA + 8
0129 
0130     .rept   SLB_NUM_BOLTED
0131     LDX_BE  r10, r11, r8
0132     cmpdi   r10, 0
0133     beq 1f
0134     LDX_BE  r9, r11, r7
0135     slbmte  r9, r10
0136 1:  addi    r7, r7, SHADOW_SLB_ENTRY_LEN
0137     addi    r8, r8, SHADOW_SLB_ENTRY_LEN
0138     .endr
0139 
0140     isync
0141     sync
0142 
0143 slb_do_exit:
0144 
0145 .endm