|
@@ -85,8 +85,33 @@ u64 vcpu_read_sys_reg(struct kvm_vcpu *vcpu, int reg)
|
|
/*
|
|
/*
|
|
* System registers listed in the switch are not saved on every
|
|
* System registers listed in the switch are not saved on every
|
|
* exit from the guest but are only saved on vcpu_put.
|
|
* exit from the guest but are only saved on vcpu_put.
|
|
|
|
+ *
|
|
|
|
+ * Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but
|
|
|
|
+ * should never be listed below, because the guest cannot modify its
|
|
|
|
+ * own MPIDR_EL1 and MPIDR_EL1 is accessed for VCPU A from VCPU B's
|
|
|
|
+ * thread when emulating cross-VCPU communication.
|
|
*/
|
|
*/
|
|
switch (reg) {
|
|
switch (reg) {
|
|
|
|
+ case CSSELR_EL1: return read_sysreg_s(SYS_CSSELR_EL1);
|
|
|
|
+ case SCTLR_EL1: return read_sysreg_s(sctlr_EL12);
|
|
|
|
+ case ACTLR_EL1: return read_sysreg_s(SYS_ACTLR_EL1);
|
|
|
|
+ case CPACR_EL1: return read_sysreg_s(cpacr_EL12);
|
|
|
|
+ case TTBR0_EL1: return read_sysreg_s(ttbr0_EL12);
|
|
|
|
+ case TTBR1_EL1: return read_sysreg_s(ttbr1_EL12);
|
|
|
|
+ case TCR_EL1: return read_sysreg_s(tcr_EL12);
|
|
|
|
+ case ESR_EL1: return read_sysreg_s(esr_EL12);
|
|
|
|
+ case AFSR0_EL1: return read_sysreg_s(afsr0_EL12);
|
|
|
|
+ case AFSR1_EL1: return read_sysreg_s(afsr1_EL12);
|
|
|
|
+ case FAR_EL1: return read_sysreg_s(far_EL12);
|
|
|
|
+ case MAIR_EL1: return read_sysreg_s(mair_EL12);
|
|
|
|
+ case VBAR_EL1: return read_sysreg_s(vbar_EL12);
|
|
|
|
+ case CONTEXTIDR_EL1: return read_sysreg_s(contextidr_EL12);
|
|
|
|
+ case TPIDR_EL0: return read_sysreg_s(SYS_TPIDR_EL0);
|
|
|
|
+ case TPIDRRO_EL0: return read_sysreg_s(SYS_TPIDRRO_EL0);
|
|
|
|
+ case TPIDR_EL1: return read_sysreg_s(SYS_TPIDR_EL1);
|
|
|
|
+ case AMAIR_EL1: return read_sysreg_s(amair_EL12);
|
|
|
|
+ case CNTKCTL_EL1: return read_sysreg_s(cntkctl_EL12);
|
|
|
|
+ case PAR_EL1: return read_sysreg_s(SYS_PAR_EL1);
|
|
}
|
|
}
|
|
|
|
|
|
immediate_read:
|
|
immediate_read:
|
|
@@ -101,8 +126,32 @@ void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg)
|
|
/*
|
|
/*
|
|
* System registers listed in the switch are not restored on every
|
|
* System registers listed in the switch are not restored on every
|
|
* entry to the guest but are only restored on vcpu_load.
|
|
* entry to the guest but are only restored on vcpu_load.
|
|
|
|
+ *
|
|
|
|
+ * Note that MPIDR_EL1 for the guest is set by KVM via VMPIDR_EL2 but
|
|
|
|
+ * should never be listed below, because the the MPIDR should only be
|
|
|
|
+ * set once, before running the VCPU, and never changed later.
|
|
*/
|
|
*/
|
|
switch (reg) {
|
|
switch (reg) {
|
|
|
|
+ case CSSELR_EL1: write_sysreg_s(val, SYS_CSSELR_EL1); return;
|
|
|
|
+ case SCTLR_EL1: write_sysreg_s(val, sctlr_EL12); return;
|
|
|
|
+ case ACTLR_EL1: write_sysreg_s(val, SYS_ACTLR_EL1); return;
|
|
|
|
+ case CPACR_EL1: write_sysreg_s(val, cpacr_EL12); return;
|
|
|
|
+ case TTBR0_EL1: write_sysreg_s(val, ttbr0_EL12); return;
|
|
|
|
+ case TTBR1_EL1: write_sysreg_s(val, ttbr1_EL12); return;
|
|
|
|
+ case TCR_EL1: write_sysreg_s(val, tcr_EL12); return;
|
|
|
|
+ case ESR_EL1: write_sysreg_s(val, esr_EL12); return;
|
|
|
|
+ case AFSR0_EL1: write_sysreg_s(val, afsr0_EL12); return;
|
|
|
|
+ case AFSR1_EL1: write_sysreg_s(val, afsr1_EL12); return;
|
|
|
|
+ case FAR_EL1: write_sysreg_s(val, far_EL12); return;
|
|
|
|
+ case MAIR_EL1: write_sysreg_s(val, mair_EL12); return;
|
|
|
|
+ case VBAR_EL1: write_sysreg_s(val, vbar_EL12); return;
|
|
|
|
+ case CONTEXTIDR_EL1: write_sysreg_s(val, contextidr_EL12); return;
|
|
|
|
+ case TPIDR_EL0: write_sysreg_s(val, SYS_TPIDR_EL0); return;
|
|
|
|
+ case TPIDRRO_EL0: write_sysreg_s(val, SYS_TPIDRRO_EL0); return;
|
|
|
|
+ case TPIDR_EL1: write_sysreg_s(val, SYS_TPIDR_EL1); return;
|
|
|
|
+ case AMAIR_EL1: write_sysreg_s(val, amair_EL12); return;
|
|
|
|
+ case CNTKCTL_EL1: write_sysreg_s(val, cntkctl_EL12); return;
|
|
|
|
+ case PAR_EL1: write_sysreg_s(val, SYS_PAR_EL1); return;
|
|
}
|
|
}
|
|
|
|
|
|
immediate_write:
|
|
immediate_write:
|