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/asm-compat.h> 10#include <asm/feature-fixups.h> 11 12#define SHADOW_SLB_ENTRY_LEN 0x10 13#define OFFSET_ESID(x) (SHADOW_SLB_ENTRY_LEN * x) 14#define OFFSET_VSID(x) ((SHADOW_SLB_ENTRY_LEN * x) + 8) 15 16/****************************************************************************** 17 * * 18 * Entry code * 19 * * 20 *****************************************************************************/ 21 22.macro LOAD_GUEST_SEGMENTS 23 24 /* Required state: 25 * 26 * MSR = ~IR|DR 27 * R13 = PACA 28 * R1 = host R1 29 * R2 = host R2 30 * R3 = shadow vcpu 31 * all other volatile GPRS = free except R4, R6 32 * SVCPU[CR] = guest CR 33 * SVCPU[XER] = guest XER 34 * SVCPU[CTR] = guest CTR 35 * SVCPU[LR] = guest LR 36 */ 37 38BEGIN_FW_FTR_SECTION 39 40 /* Declare SLB shadow as 0 entries big */ 41 42 ld r11, PACA_SLBSHADOWPTR(r13) 43 li r8, 0 44 stb r8, 3(r11) 45 46END_FW_FTR_SECTION_IFSET(FW_FEATURE_LPAR) 47 48 /* Flush SLB */ 49 50 li r10, 0 51 slbmte r10, r10 52 slbia 53 54 /* Fill SLB with our shadow */ 55 56 lbz r12, SVCPU_SLB_MAX(r3) 57 mulli r12, r12, 16 58 addi r12, r12, SVCPU_SLB 59 add r12, r12, r3 60 61 /* for (r11 = kvm_slb; r11 < kvm_slb + kvm_slb_size; r11+=slb_entry) */ 62 li r11, SVCPU_SLB 63 add r11, r11, r3 64 65slb_loop_enter: 66 67 ld r10, 0(r11) 68 69 andis. r9, r10, SLB_ESID_V@h 70 beq slb_loop_enter_skip 71 72 ld r9, 8(r11) 73 slbmte r9, r10 74 75slb_loop_enter_skip: 76 addi r11, r11, 16 77 cmpd cr0, r11, r12 78 blt slb_loop_enter 79 80slb_do_enter: 81 82.endm 83 84/****************************************************************************** 85 * * 86 * Exit code * 87 * * 88 *****************************************************************************/ 89 90.macro LOAD_HOST_SEGMENTS 91 92 /* Register usage at this point: 93 * 94 * R1 = host R1 95 * R2 = host R2 96 * R12 = exit handler id 97 * R13 = shadow vcpu - SHADOW_VCPU_OFF [=PACA on PPC64] 98 * SVCPU.* = guest * 99 * SVCPU[CR] = guest CR 100 * SVCPU[XER] = guest XER 101 * SVCPU[CTR] = guest CTR 102 * SVCPU[LR] = guest LR 103 * 104 */ 105 106 /* Remove all SLB entries that are in use. */ 107 108 li r0, 0 109 slbmte r0, r0 110 slbia 111 112 /* Restore bolted entries from the shadow */ 113 114 ld r11, PACA_SLBSHADOWPTR(r13) 115 116BEGIN_FW_FTR_SECTION 117 118 /* Declare SLB shadow as SLB_NUM_BOLTED entries big */ 119 120 li r8, SLB_NUM_BOLTED 121 stb r8, 3(r11) 122 123END_FW_FTR_SECTION_IFSET(FW_FEATURE_LPAR) 124 125 /* Manually load all entries from shadow SLB */ 126 127 li r8, SLBSHADOW_SAVEAREA 128 li r7, SLBSHADOW_SAVEAREA + 8 129 130 .rept SLB_NUM_BOLTED 131 LDX_BE r10, r11, r8 132 cmpdi r10, 0 133 beq 1f 134 LDX_BE r9, r11, r7 135 slbmte r9, r10 1361: addi r7, r7, SHADOW_SLB_ENTRY_LEN 137 addi r8, r8, SHADOW_SLB_ENTRY_LEN 138 .endr 139 140 isync 141 sync 142 143slb_do_exit: 144 145.endm 146