forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
3.1 KiB
145 lines
3.1 KiB
/* SPDX-License-Identifier: GPL-2.0-only */ |
|
/* |
|
* |
|
* Copyright SUSE Linux Products GmbH 2009 |
|
* |
|
* Authors: Alexander Graf <agraf@suse.de> |
|
*/ |
|
|
|
#include <asm/asm-compat.h> |
|
#include <asm/feature-fixups.h> |
|
|
|
#define SHADOW_SLB_ENTRY_LEN 0x10 |
|
#define OFFSET_ESID(x) (SHADOW_SLB_ENTRY_LEN * x) |
|
#define OFFSET_VSID(x) ((SHADOW_SLB_ENTRY_LEN * x) + 8) |
|
|
|
/****************************************************************************** |
|
* * |
|
* Entry code * |
|
* * |
|
*****************************************************************************/ |
|
|
|
.macro LOAD_GUEST_SEGMENTS |
|
|
|
/* Required state: |
|
* |
|
* MSR = ~IR|DR |
|
* R13 = PACA |
|
* R1 = host R1 |
|
* R2 = host R2 |
|
* R3 = shadow vcpu |
|
* all other volatile GPRS = free except R4, R6 |
|
* SVCPU[CR] = guest CR |
|
* SVCPU[XER] = guest XER |
|
* SVCPU[CTR] = guest CTR |
|
* SVCPU[LR] = guest LR |
|
*/ |
|
|
|
BEGIN_FW_FTR_SECTION |
|
|
|
/* Declare SLB shadow as 0 entries big */ |
|
|
|
ld r11, PACA_SLBSHADOWPTR(r13) |
|
li r8, 0 |
|
stb r8, 3(r11) |
|
|
|
END_FW_FTR_SECTION_IFSET(FW_FEATURE_LPAR) |
|
|
|
/* Flush SLB */ |
|
|
|
li r10, 0 |
|
slbmte r10, r10 |
|
slbia |
|
|
|
/* Fill SLB with our shadow */ |
|
|
|
lbz r12, SVCPU_SLB_MAX(r3) |
|
mulli r12, r12, 16 |
|
addi r12, r12, SVCPU_SLB |
|
add r12, r12, r3 |
|
|
|
/* for (r11 = kvm_slb; r11 < kvm_slb + kvm_slb_size; r11+=slb_entry) */ |
|
li r11, SVCPU_SLB |
|
add r11, r11, r3 |
|
|
|
slb_loop_enter: |
|
|
|
ld r10, 0(r11) |
|
|
|
andis. r9, r10, SLB_ESID_V@h |
|
beq slb_loop_enter_skip |
|
|
|
ld r9, 8(r11) |
|
slbmte r9, r10 |
|
|
|
slb_loop_enter_skip: |
|
addi r11, r11, 16 |
|
cmpd cr0, r11, r12 |
|
blt slb_loop_enter |
|
|
|
slb_do_enter: |
|
|
|
.endm |
|
|
|
/****************************************************************************** |
|
* * |
|
* Exit code * |
|
* * |
|
*****************************************************************************/ |
|
|
|
.macro LOAD_HOST_SEGMENTS |
|
|
|
/* Register usage at this point: |
|
* |
|
* R1 = host R1 |
|
* R2 = host R2 |
|
* R12 = exit handler id |
|
* R13 = shadow vcpu - SHADOW_VCPU_OFF [=PACA on PPC64] |
|
* SVCPU.* = guest * |
|
* SVCPU[CR] = guest CR |
|
* SVCPU[XER] = guest XER |
|
* SVCPU[CTR] = guest CTR |
|
* SVCPU[LR] = guest LR |
|
* |
|
*/ |
|
|
|
/* Remove all SLB entries that are in use. */ |
|
|
|
li r0, 0 |
|
slbmte r0, r0 |
|
slbia |
|
|
|
/* Restore bolted entries from the shadow */ |
|
|
|
ld r11, PACA_SLBSHADOWPTR(r13) |
|
|
|
BEGIN_FW_FTR_SECTION |
|
|
|
/* Declare SLB shadow as SLB_NUM_BOLTED entries big */ |
|
|
|
li r8, SLB_NUM_BOLTED |
|
stb r8, 3(r11) |
|
|
|
END_FW_FTR_SECTION_IFSET(FW_FEATURE_LPAR) |
|
|
|
/* Manually load all entries from shadow SLB */ |
|
|
|
li r8, SLBSHADOW_SAVEAREA |
|
li r7, SLBSHADOW_SAVEAREA + 8 |
|
|
|
.rept SLB_NUM_BOLTED |
|
LDX_BE r10, r11, r8 |
|
cmpdi r10, 0 |
|
beq 1f |
|
LDX_BE r9, r11, r7 |
|
slbmte r9, r10 |
|
1: addi r7, r7, SHADOW_SLB_ENTRY_LEN |
|
addi r8, r8, SHADOW_SLB_ENTRY_LEN |
|
.endr |
|
|
|
isync |
|
sync |
|
|
|
slb_do_exit: |
|
|
|
.endm
|
|
|