/* SPDX-License-Identifier: GPL-2.0-only */
/*
*
* Copyright SUSE Linux Products GmbH 2009
*
* Authors: Alexander Graf <agraf@suse.de>
*/
/******************************************************************************
* *
* Entry code *
* *
*****************************************************************************/
.macro LOAD_GUEST_SEGMENTS
/* Required state:
*
* MSR = ~IR|DR
* 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
*/
#define XCHG_SR(n) lwz r9, (SVCPU_SR+(n*4 ))(r3); \
mtsr n, r9
XCHG_SR(0 )
XCHG_SR(1 )
XCHG_SR(2 )
XCHG_SR(3 )
XCHG_SR(4 )
XCHG_SR(5 )
XCHG_SR(6 )
XCHG_SR(7 )
XCHG_SR(8 )
XCHG_SR(9 )
XCHG_SR(10 )
XCHG_SR(11 )
XCHG_SR(12 )
XCHG_SR(13 )
XCHG_SR(14 )
XCHG_SR(15 )
/* Clear BATs. */
#define KVM_KILL_BAT(n, reg) \
mtspr SPRN_IBAT##n##U,reg; \
mtspr SPRN_IBAT##n##L,reg; \
mtspr SPRN_DBAT##n##U,reg; \
mtspr SPRN_DBAT##n##L,reg; \
li r9, 0
KVM_KILL_BAT(0 , r9)
KVM_KILL_BAT(1 , r9)
KVM_KILL_BAT(2 , r9)
KVM_KILL_BAT(3 , r9)
.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
* SVCPU.* = guest *
* SVCPU[CR] = guest CR
* SVCPU[XER] = guest XER
* SVCPU[CTR] = guest CTR
* SVCPU[LR] = guest LR
*
*/
/* Restore BATs */
/* We only overwrite the upper part, so we only restoree
the upper part. */
#define KVM_LOAD_BAT(n, reg, RA, RB) \
lwz RA,(n*16 )+0 (reg); \
lwz RB,(n*16 )+4 (reg); \
mtspr SPRN_IBAT##n##U,RA; \
mtspr SPRN_IBAT##n##L,RB; \
lwz RA,(n*16 )+8 (reg); \
lwz RB,(n*16 )+12 (reg); \
mtspr SPRN_DBAT##n##U,RA; \
mtspr SPRN_DBAT##n##L,RB; \
lis r9, BATS@ha
addi r9, r9, BATS@l
tophys(r9, r9)
KVM_LOAD_BAT(0 , r9, r10, r11)
KVM_LOAD_BAT(1 , r9, r10, r11)
KVM_LOAD_BAT(2 , r9, r10, r11)
KVM_LOAD_BAT(3 , r9, r10, r11)
/* Restore Segment Registers */
/* 0xc - 0xf */
li r0, 4
mtctr r0
LOAD_REG_IMMEDIATE(r3, 0 x20000000 | (0 x111 * 0 xc))
lis r4, 0 xc000
3 : mtsrin r3, r4
addi r3, r3, 0 x111 /* increment VSID */
addis r4, r4, 0 x1000 /* address of next segment */
bdnz 3 b
/* 0x0 - 0xb */
/* switch_mmu_context() needs paging, let's enable it */
mfmsr r9
ori r11, r9, MSR_DR
mtmsr r11
sync
/* switch_mmu_context() clobbers r12, rescue it */
SAVE_GPR(12 , r1)
/* Calling switch_mmu_context(<inv>, current->mm, <inv>); */
lwz r4, MM(r2)
bl switch_mmu_context
/* restore r12 */
REST_GPR(12 , r1)
/* Disable paging again */
mfmsr r9
li r6, MSR_DR
andc r9, r9, r6
mtmsr r9
sync
.endm
Messung V0.5 in Prozent C=96 H=97 G=96
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-08)
¤
*© Formatika GbR, Deutschland