linux/arch/arm64/kvm/hyp/sysreg-sr.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2012-2015 - ARM Ltd
   3 * Author: Marc Zyngier <marc.zyngier@arm.com>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License version 2 as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16 */
  17
  18#include <linux/compiler.h>
  19#include <linux/kvm_host.h>
  20
  21#include <asm/kvm_asm.h>
  22#include <asm/kvm_hyp.h>
  23
  24/* Yes, this does nothing, on purpose */
  25static void __hyp_text __sysreg_do_nothing(struct kvm_cpu_context *ctxt) { }
  26
  27/*
  28 * Non-VHE: Both host and guest must save everything.
  29 *
  30 * VHE: Host must save tpidr*_el[01], actlr_el1, mdscr_el1, sp0, pc,
  31 * pstate, and guest must save everything.
  32 */
  33
  34static void __hyp_text __sysreg_save_common_state(struct kvm_cpu_context *ctxt)
  35{
  36        ctxt->sys_regs[ACTLR_EL1]       = read_sysreg(actlr_el1);
  37        ctxt->sys_regs[TPIDR_EL0]       = read_sysreg(tpidr_el0);
  38        ctxt->sys_regs[TPIDRRO_EL0]     = read_sysreg(tpidrro_el0);
  39        ctxt->sys_regs[TPIDR_EL1]       = read_sysreg(tpidr_el1);
  40        ctxt->sys_regs[MDSCR_EL1]       = read_sysreg(mdscr_el1);
  41        ctxt->gp_regs.regs.sp           = read_sysreg(sp_el0);
  42        ctxt->gp_regs.regs.pc           = read_sysreg_el2(elr);
  43        ctxt->gp_regs.regs.pstate       = read_sysreg_el2(spsr);
  44}
  45
  46static void __hyp_text __sysreg_save_state(struct kvm_cpu_context *ctxt)
  47{
  48        ctxt->sys_regs[MPIDR_EL1]       = read_sysreg(vmpidr_el2);
  49        ctxt->sys_regs[CSSELR_EL1]      = read_sysreg(csselr_el1);
  50        ctxt->sys_regs[SCTLR_EL1]       = read_sysreg_el1(sctlr);
  51        ctxt->sys_regs[CPACR_EL1]       = read_sysreg_el1(cpacr);
  52        ctxt->sys_regs[TTBR0_EL1]       = read_sysreg_el1(ttbr0);
  53        ctxt->sys_regs[TTBR1_EL1]       = read_sysreg_el1(ttbr1);
  54        ctxt->sys_regs[TCR_EL1]         = read_sysreg_el1(tcr);
  55        ctxt->sys_regs[ESR_EL1]         = read_sysreg_el1(esr);
  56        ctxt->sys_regs[AFSR0_EL1]       = read_sysreg_el1(afsr0);
  57        ctxt->sys_regs[AFSR1_EL1]       = read_sysreg_el1(afsr1);
  58        ctxt->sys_regs[FAR_EL1]         = read_sysreg_el1(far);
  59        ctxt->sys_regs[MAIR_EL1]        = read_sysreg_el1(mair);
  60        ctxt->sys_regs[VBAR_EL1]        = read_sysreg_el1(vbar);
  61        ctxt->sys_regs[CONTEXTIDR_EL1]  = read_sysreg_el1(contextidr);
  62        ctxt->sys_regs[AMAIR_EL1]       = read_sysreg_el1(amair);
  63        ctxt->sys_regs[CNTKCTL_EL1]     = read_sysreg_el1(cntkctl);
  64        ctxt->sys_regs[PAR_EL1]         = read_sysreg(par_el1);
  65
  66        ctxt->gp_regs.sp_el1            = read_sysreg(sp_el1);
  67        ctxt->gp_regs.elr_el1           = read_sysreg_el1(elr);
  68        ctxt->gp_regs.spsr[KVM_SPSR_EL1]= read_sysreg_el1(spsr);
  69}
  70
  71static hyp_alternate_select(__sysreg_call_save_host_state,
  72                            __sysreg_save_state, __sysreg_do_nothing,
  73                            ARM64_HAS_VIRT_HOST_EXTN);
  74
  75void __hyp_text __sysreg_save_host_state(struct kvm_cpu_context *ctxt)
  76{
  77        __sysreg_call_save_host_state()(ctxt);
  78        __sysreg_save_common_state(ctxt);
  79}
  80
  81void __hyp_text __sysreg_save_guest_state(struct kvm_cpu_context *ctxt)
  82{
  83        __sysreg_save_state(ctxt);
  84        __sysreg_save_common_state(ctxt);
  85}
  86
  87static void __hyp_text __sysreg_restore_common_state(struct kvm_cpu_context *ctxt)
  88{
  89        write_sysreg(ctxt->sys_regs[ACTLR_EL1],   actlr_el1);
  90        write_sysreg(ctxt->sys_regs[TPIDR_EL0],   tpidr_el0);
  91        write_sysreg(ctxt->sys_regs[TPIDRRO_EL0], tpidrro_el0);
  92        write_sysreg(ctxt->sys_regs[TPIDR_EL1],   tpidr_el1);
  93        write_sysreg(ctxt->sys_regs[MDSCR_EL1],   mdscr_el1);
  94        write_sysreg(ctxt->gp_regs.regs.sp,       sp_el0);
  95        write_sysreg_el2(ctxt->gp_regs.regs.pc,   elr);
  96        write_sysreg_el2(ctxt->gp_regs.regs.pstate, spsr);
  97}
  98
  99static void __hyp_text __sysreg_restore_state(struct kvm_cpu_context *ctxt)
 100{
 101        write_sysreg(ctxt->sys_regs[MPIDR_EL1],         vmpidr_el2);
 102        write_sysreg(ctxt->sys_regs[CSSELR_EL1],        csselr_el1);
 103        write_sysreg_el1(ctxt->sys_regs[SCTLR_EL1],     sctlr);
 104        write_sysreg_el1(ctxt->sys_regs[CPACR_EL1],     cpacr);
 105        write_sysreg_el1(ctxt->sys_regs[TTBR0_EL1],     ttbr0);
 106        write_sysreg_el1(ctxt->sys_regs[TTBR1_EL1],     ttbr1);
 107        write_sysreg_el1(ctxt->sys_regs[TCR_EL1],       tcr);
 108        write_sysreg_el1(ctxt->sys_regs[ESR_EL1],       esr);
 109        write_sysreg_el1(ctxt->sys_regs[AFSR0_EL1],     afsr0);
 110        write_sysreg_el1(ctxt->sys_regs[AFSR1_EL1],     afsr1);
 111        write_sysreg_el1(ctxt->sys_regs[FAR_EL1],       far);
 112        write_sysreg_el1(ctxt->sys_regs[MAIR_EL1],      mair);
 113        write_sysreg_el1(ctxt->sys_regs[VBAR_EL1],      vbar);
 114        write_sysreg_el1(ctxt->sys_regs[CONTEXTIDR_EL1],contextidr);
 115        write_sysreg_el1(ctxt->sys_regs[AMAIR_EL1],     amair);
 116        write_sysreg_el1(ctxt->sys_regs[CNTKCTL_EL1],   cntkctl);
 117        write_sysreg(ctxt->sys_regs[PAR_EL1],           par_el1);
 118
 119        write_sysreg(ctxt->gp_regs.sp_el1,              sp_el1);
 120        write_sysreg_el1(ctxt->gp_regs.elr_el1,         elr);
 121        write_sysreg_el1(ctxt->gp_regs.spsr[KVM_SPSR_EL1],spsr);
 122}
 123
 124static hyp_alternate_select(__sysreg_call_restore_host_state,
 125                            __sysreg_restore_state, __sysreg_do_nothing,
 126                            ARM64_HAS_VIRT_HOST_EXTN);
 127
 128void __hyp_text __sysreg_restore_host_state(struct kvm_cpu_context *ctxt)
 129{
 130        __sysreg_call_restore_host_state()(ctxt);
 131        __sysreg_restore_common_state(ctxt);
 132}
 133
 134void __hyp_text __sysreg_restore_guest_state(struct kvm_cpu_context *ctxt)
 135{
 136        __sysreg_restore_state(ctxt);
 137        __sysreg_restore_common_state(ctxt);
 138}
 139
 140void __hyp_text __sysreg32_save_state(struct kvm_vcpu *vcpu)
 141{
 142        u64 *spsr, *sysreg;
 143
 144        if (read_sysreg(hcr_el2) & HCR_RW)
 145                return;
 146
 147        spsr = vcpu->arch.ctxt.gp_regs.spsr;
 148        sysreg = vcpu->arch.ctxt.sys_regs;
 149
 150        spsr[KVM_SPSR_ABT] = read_sysreg(spsr_abt);
 151        spsr[KVM_SPSR_UND] = read_sysreg(spsr_und);
 152        spsr[KVM_SPSR_IRQ] = read_sysreg(spsr_irq);
 153        spsr[KVM_SPSR_FIQ] = read_sysreg(spsr_fiq);
 154
 155        sysreg[DACR32_EL2] = read_sysreg(dacr32_el2);
 156        sysreg[IFSR32_EL2] = read_sysreg(ifsr32_el2);
 157
 158        if (__fpsimd_enabled())
 159                sysreg[FPEXC32_EL2] = read_sysreg(fpexc32_el2);
 160
 161        if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
 162                sysreg[DBGVCR32_EL2] = read_sysreg(dbgvcr32_el2);
 163}
 164
 165void __hyp_text __sysreg32_restore_state(struct kvm_vcpu *vcpu)
 166{
 167        u64 *spsr, *sysreg;
 168
 169        if (read_sysreg(hcr_el2) & HCR_RW)
 170                return;
 171
 172        spsr = vcpu->arch.ctxt.gp_regs.spsr;
 173        sysreg = vcpu->arch.ctxt.sys_regs;
 174
 175        write_sysreg(spsr[KVM_SPSR_ABT], spsr_abt);
 176        write_sysreg(spsr[KVM_SPSR_UND], spsr_und);
 177        write_sysreg(spsr[KVM_SPSR_IRQ], spsr_irq);
 178        write_sysreg(spsr[KVM_SPSR_FIQ], spsr_fiq);
 179
 180        write_sysreg(sysreg[DACR32_EL2], dacr32_el2);
 181        write_sysreg(sysreg[IFSR32_EL2], ifsr32_el2);
 182
 183        if (vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY)
 184                write_sysreg(sysreg[DBGVCR32_EL2], dbgvcr32_el2);
 185}
 186