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/****************************************************************************** 10 * * 11 * Entry code * 12 * * 13 *****************************************************************************/ 14 15.macro LOAD_GUEST_SEGMENTS 16 17 /* Required state: 18 * 19 * MSR = ~IR|DR 20 * R1 = host R1 21 * R2 = host R2 22 * R3 = shadow vcpu 23 * all other volatile GPRS = free except R4, R6 24 * SVCPU[CR] = guest CR 25 * SVCPU[XER] = guest XER 26 * SVCPU[CTR] = guest CTR 27 * SVCPU[LR] = guest LR 28 */ 29 30#define XCHG_SR(n) lwz r9, (SVCPU_SR+(n*4))(r3); \ 31 mtsr n, r9 32 33 XCHG_SR(0) 34 XCHG_SR(1) 35 XCHG_SR(2) 36 XCHG_SR(3) 37 XCHG_SR(4) 38 XCHG_SR(5) 39 XCHG_SR(6) 40 XCHG_SR(7) 41 XCHG_SR(8) 42 XCHG_SR(9) 43 XCHG_SR(10) 44 XCHG_SR(11) 45 XCHG_SR(12) 46 XCHG_SR(13) 47 XCHG_SR(14) 48 XCHG_SR(15) 49 50 /* Clear BATs. */ 51 52#define KVM_KILL_BAT(n, reg) \ 53 mtspr SPRN_IBAT##n##U,reg; \ 54 mtspr SPRN_IBAT##n##L,reg; \ 55 mtspr SPRN_DBAT##n##U,reg; \ 56 mtspr SPRN_DBAT##n##L,reg; \ 57 58 li r9, 0 59 KVM_KILL_BAT(0, r9) 60 KVM_KILL_BAT(1, r9) 61 KVM_KILL_BAT(2, r9) 62 KVM_KILL_BAT(3, r9) 63 64.endm 65 66/****************************************************************************** 67 * * 68 * Exit code * 69 * * 70 *****************************************************************************/ 71 72.macro LOAD_HOST_SEGMENTS 73 74 /* Register usage at this point: 75 * 76 * R1 = host R1 77 * R2 = host R2 78 * R12 = exit handler id 79 * R13 = shadow vcpu - SHADOW_VCPU_OFF 80 * SVCPU.* = guest * 81 * SVCPU[CR] = guest CR 82 * SVCPU[XER] = guest XER 83 * SVCPU[CTR] = guest CTR 84 * SVCPU[LR] = guest LR 85 * 86 */ 87 88 /* Restore BATs */ 89 90 /* We only overwrite the upper part, so we only restoree 91 the upper part. */ 92#define KVM_LOAD_BAT(n, reg, RA, RB) \ 93 lwz RA,(n*16)+0(reg); \ 94 lwz RB,(n*16)+4(reg); \ 95 mtspr SPRN_IBAT##n##U,RA; \ 96 mtspr SPRN_IBAT##n##L,RB; \ 97 lwz RA,(n*16)+8(reg); \ 98 lwz RB,(n*16)+12(reg); \ 99 mtspr SPRN_DBAT##n##U,RA; \ 100 mtspr SPRN_DBAT##n##L,RB; \ 101 102 lis r9, BATS@ha 103 addi r9, r9, BATS@l 104 tophys(r9, r9) 105 KVM_LOAD_BAT(0, r9, r10, r11) 106 KVM_LOAD_BAT(1, r9, r10, r11) 107 KVM_LOAD_BAT(2, r9, r10, r11) 108 KVM_LOAD_BAT(3, r9, r10, r11) 109 110 /* Restore Segment Registers */ 111 112 /* 0xc - 0xf */ 113 114 li r0, 4 115 mtctr r0 116 LOAD_REG_IMMEDIATE(r3, 0x20000000 | (0x111 * 0xc)) 117 lis r4, 0xc000 1183: mtsrin r3, r4 119 addi r3, r3, 0x111 /* increment VSID */ 120 addis r4, r4, 0x1000 /* address of next segment */ 121 bdnz 3b 122 123 /* 0x0 - 0xb */ 124 125 /* 'current->mm' needs to be in r4 */ 126 tophys(r4, r2) 127 lwz r4, MM(r4) 128 tophys(r4, r4) 129 /* This only clobbers r0, r3, r4 and r5 */ 130 bl switch_mmu_context 131 132.endm 133