Skip to content

Commit

Permalink
arm/arm64: KVM: Add smccc accessors to PSCI code
Browse files Browse the repository at this point in the history
Instead of open coding the accesses to the various registers,
let's add explicit SMCCC accessors.

Reviewed-by: Christoffer Dall <[email protected]>
Tested-by: Ard Biesheuvel <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
Signed-off-by: Catalin Marinas <[email protected]>
  • Loading branch information
Marc Zyngier authored and ctmarinas committed Feb 6, 2018
1 parent d0a144f commit 84684fe
Showing 1 changed file with 42 additions and 10 deletions.
52 changes: 42 additions & 10 deletions virt/kvm/arm/psci.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,38 @@

#define AFFINITY_MASK(level) ~((0x1UL << ((level) * MPIDR_LEVEL_BITS)) - 1)

static u32 smccc_get_function(struct kvm_vcpu *vcpu)
{
return vcpu_get_reg(vcpu, 0);
}

static unsigned long smccc_get_arg1(struct kvm_vcpu *vcpu)
{
return vcpu_get_reg(vcpu, 1);
}

static unsigned long smccc_get_arg2(struct kvm_vcpu *vcpu)
{
return vcpu_get_reg(vcpu, 2);
}

static unsigned long smccc_get_arg3(struct kvm_vcpu *vcpu)
{
return vcpu_get_reg(vcpu, 3);
}

static void smccc_set_retval(struct kvm_vcpu *vcpu,
unsigned long a0,
unsigned long a1,
unsigned long a2,
unsigned long a3)
{
vcpu_set_reg(vcpu, 0, a0);
vcpu_set_reg(vcpu, 1, a1);
vcpu_set_reg(vcpu, 2, a2);
vcpu_set_reg(vcpu, 3, a3);
}

static unsigned long psci_affinity_mask(unsigned long affinity_level)
{
if (affinity_level <= 3)
Expand Down Expand Up @@ -77,7 +109,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
unsigned long context_id;
phys_addr_t target_pc;

cpu_id = vcpu_get_reg(source_vcpu, 1) & MPIDR_HWID_BITMASK;
cpu_id = smccc_get_arg1(source_vcpu) & MPIDR_HWID_BITMASK;
if (vcpu_mode_is_32bit(source_vcpu))
cpu_id &= ~((u32) 0);

Expand All @@ -96,8 +128,8 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
return PSCI_RET_INVALID_PARAMS;
}

target_pc = vcpu_get_reg(source_vcpu, 2);
context_id = vcpu_get_reg(source_vcpu, 3);
target_pc = smccc_get_arg2(source_vcpu);
context_id = smccc_get_arg3(source_vcpu);

kvm_reset_vcpu(vcpu);

Expand All @@ -116,7 +148,7 @@ static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
* NOTE: We always update r0 (or x0) because for PSCI v0.1
* the general puspose registers are undefined upon CPU_ON.
*/
vcpu_set_reg(vcpu, 0, context_id);
smccc_set_retval(vcpu, context_id, 0, 0, 0);
vcpu->arch.power_off = false;
smp_mb(); /* Make sure the above is visible */

Expand All @@ -136,8 +168,8 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
struct kvm *kvm = vcpu->kvm;
struct kvm_vcpu *tmp;

target_affinity = vcpu_get_reg(vcpu, 1);
lowest_affinity_level = vcpu_get_reg(vcpu, 2);
target_affinity = smccc_get_arg1(vcpu);
lowest_affinity_level = smccc_get_arg2(vcpu);

/* Determine target affinity mask */
target_affinity_mask = psci_affinity_mask(lowest_affinity_level);
Expand Down Expand Up @@ -210,7 +242,7 @@ int kvm_psci_version(struct kvm_vcpu *vcpu)
static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
{
struct kvm *kvm = vcpu->kvm;
unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
u32 psci_fn = smccc_get_function(vcpu);
unsigned long val;
int ret = 1;

Expand Down Expand Up @@ -277,14 +309,14 @@ static int kvm_psci_0_2_call(struct kvm_vcpu *vcpu)
break;
}

vcpu_set_reg(vcpu, 0, val);
smccc_set_retval(vcpu, val, 0, 0, 0);
return ret;
}

static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
{
struct kvm *kvm = vcpu->kvm;
unsigned long psci_fn = vcpu_get_reg(vcpu, 0) & ~((u32) 0);
u32 psci_fn = smccc_get_function(vcpu);
unsigned long val;

switch (psci_fn) {
Expand All @@ -302,7 +334,7 @@ static int kvm_psci_0_1_call(struct kvm_vcpu *vcpu)
break;
}

vcpu_set_reg(vcpu, 0, val);
smccc_set_retval(vcpu, val, 0, 0, 0);
return 1;
}

Expand Down

0 comments on commit 84684fe

Please sign in to comment.