mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 02:50:49 +09:00
ANDROID: KVM: arm64: Move vgic state between host and hypervisor vcpu structures
Since the world switch vgic code operates on the hypervisor data structure, move the state back and forth between the host and hypervisor vcpu. This is currently limited to the VMCR and APR registers, but further patches will deal with the rest of the state. Note that some of the control settings (such as SRE) are always set to the same value. This will eventually be moved to initialisation time for the hypervisor structures. Signed-off-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Will Deacon <willdeacon@google.com> Bug: 233587962 Change-Id: I8a3a9009ce3408fe06ea272504f4f71c3d47b7bf
This commit is contained in:
committed by
Will Deacon
parent
c86b8a4a5e
commit
221497c558
@@ -603,6 +603,16 @@ static struct kvm_vcpu *__get_host_hyp_vcpus(struct kvm_vcpu *arg,
|
||||
__get_host_hyp_vcpus(__vcpu, hyp_vcpup); \
|
||||
})
|
||||
|
||||
#define get_host_hyp_vcpus_from_vgic_v3_cpu_if(ctxt, regnr, hyp_vcpup) \
|
||||
({ \
|
||||
DECLARE_REG(struct vgic_v3_cpu_if *, cif, ctxt, regnr); \
|
||||
struct kvm_vcpu *__vcpu = container_of(cif, \
|
||||
struct kvm_vcpu, \
|
||||
arch.vgic_cpu.vgic_v3); \
|
||||
\
|
||||
__get_host_hyp_vcpus(__vcpu, hyp_vcpup); \
|
||||
})
|
||||
|
||||
static void handle___kvm_vcpu_run(struct kvm_cpu_context *host_ctxt)
|
||||
{
|
||||
struct pkvm_hyp_vcpu *hyp_vcpu;
|
||||
@@ -758,16 +768,63 @@ static void handle___kvm_get_mdcr_el2(struct kvm_cpu_context *host_ctxt)
|
||||
|
||||
static void handle___vgic_v3_save_vmcr_aprs(struct kvm_cpu_context *host_ctxt)
|
||||
{
|
||||
DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1);
|
||||
struct pkvm_hyp_vcpu *hyp_vcpu;
|
||||
struct kvm_vcpu *host_vcpu;
|
||||
|
||||
__vgic_v3_save_vmcr_aprs(kern_hyp_va(cpu_if));
|
||||
host_vcpu = get_host_hyp_vcpus_from_vgic_v3_cpu_if(host_ctxt, 1,
|
||||
&hyp_vcpu);
|
||||
if (!host_vcpu)
|
||||
return;
|
||||
|
||||
if (unlikely(hyp_vcpu)) {
|
||||
struct vgic_v3_cpu_if *hyp_cpu_if, *host_cpu_if;
|
||||
int i;
|
||||
|
||||
hyp_cpu_if = &hyp_vcpu->vcpu.arch.vgic_cpu.vgic_v3;
|
||||
__vgic_v3_save_vmcr_aprs(hyp_cpu_if);
|
||||
|
||||
host_cpu_if = &host_vcpu->arch.vgic_cpu.vgic_v3;
|
||||
host_cpu_if->vgic_vmcr = hyp_cpu_if->vgic_vmcr;
|
||||
for (i = 0; i < ARRAY_SIZE(host_cpu_if->vgic_ap0r); i++) {
|
||||
host_cpu_if->vgic_ap0r[i] = hyp_cpu_if->vgic_ap0r[i];
|
||||
host_cpu_if->vgic_ap1r[i] = hyp_cpu_if->vgic_ap1r[i];
|
||||
}
|
||||
} else {
|
||||
__vgic_v3_save_vmcr_aprs(&host_vcpu->arch.vgic_cpu.vgic_v3);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle___vgic_v3_restore_vmcr_aprs(struct kvm_cpu_context *host_ctxt)
|
||||
{
|
||||
DECLARE_REG(struct vgic_v3_cpu_if *, cpu_if, host_ctxt, 1);
|
||||
struct pkvm_hyp_vcpu *hyp_vcpu;
|
||||
struct kvm_vcpu *host_vcpu;
|
||||
|
||||
__vgic_v3_restore_vmcr_aprs(kern_hyp_va(cpu_if));
|
||||
host_vcpu = get_host_hyp_vcpus_from_vgic_v3_cpu_if(host_ctxt, 1,
|
||||
&hyp_vcpu);
|
||||
if (!host_vcpu)
|
||||
return;
|
||||
|
||||
if (unlikely(hyp_vcpu)) {
|
||||
struct vgic_v3_cpu_if *hyp_cpu_if, *host_cpu_if;
|
||||
int i;
|
||||
|
||||
hyp_cpu_if = &hyp_vcpu->vcpu.arch.vgic_cpu.vgic_v3;
|
||||
host_cpu_if = &host_vcpu->arch.vgic_cpu.vgic_v3;
|
||||
|
||||
hyp_cpu_if->vgic_vmcr = host_cpu_if->vgic_vmcr;
|
||||
/* Should be a one-off */
|
||||
hyp_cpu_if->vgic_sre = (ICC_SRE_EL1_DIB |
|
||||
ICC_SRE_EL1_DFB |
|
||||
ICC_SRE_EL1_SRE);
|
||||
for (i = 0; i < ARRAY_SIZE(host_cpu_if->vgic_ap0r); i++) {
|
||||
hyp_cpu_if->vgic_ap0r[i] = host_cpu_if->vgic_ap0r[i];
|
||||
hyp_cpu_if->vgic_ap1r[i] = host_cpu_if->vgic_ap1r[i];
|
||||
}
|
||||
|
||||
__vgic_v3_restore_vmcr_aprs(hyp_cpu_if);
|
||||
} else {
|
||||
__vgic_v3_restore_vmcr_aprs(&host_vcpu->arch.vgic_cpu.vgic_v3);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle___pkvm_init(struct kvm_cpu_context *host_ctxt)
|
||||
|
||||
Reference in New Issue
Block a user