Skip to content

Commit

Permalink
selftests: KVM: Create helper for making SMCCC calls
Browse files Browse the repository at this point in the history
The PSCI and PV stolen time tests both need to make SMCCC calls within
the guest. Create a helper for making SMCCC calls and rework the
existing tests to use the library function.

Signed-off-by: Oliver Upton <oupton@google.com>
Reviewed-by: Andrew Jones <drjones@redhat.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20220409184549.1681189-11-oupton@google.com
  • Loading branch information
Oliver Upton authored and Marc Zyngier committed May 3, 2022
1 parent bf08515 commit e918e2b
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 27 deletions.
25 changes: 8 additions & 17 deletions tools/testing/selftests/kvm/aarch64/psci_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,32 +26,23 @@
static uint64_t psci_cpu_on(uint64_t target_cpu, uint64_t entry_addr,
uint64_t context_id)
{
register uint64_t x0 asm("x0") = PSCI_0_2_FN64_CPU_ON;
register uint64_t x1 asm("x1") = target_cpu;
register uint64_t x2 asm("x2") = entry_addr;
register uint64_t x3 asm("x3") = context_id;
struct arm_smccc_res res;

asm("hvc #0"
: "=r"(x0)
: "r"(x0), "r"(x1), "r"(x2), "r"(x3)
: "memory");
smccc_hvc(PSCI_0_2_FN64_CPU_ON, target_cpu, entry_addr, context_id,
0, 0, 0, 0, &res);

return x0;
return res.a0;
}

static uint64_t psci_affinity_info(uint64_t target_affinity,
uint64_t lowest_affinity_level)
{
register uint64_t x0 asm("x0") = PSCI_0_2_FN64_AFFINITY_INFO;
register uint64_t x1 asm("x1") = target_affinity;
register uint64_t x2 asm("x2") = lowest_affinity_level;
struct arm_smccc_res res;

asm("hvc #0"
: "=r"(x0)
: "r"(x0), "r"(x1), "r"(x2)
: "memory");
smccc_hvc(PSCI_0_2_FN64_AFFINITY_INFO, target_affinity, lowest_affinity_level,
0, 0, 0, 0, 0, &res);

return x0;
return res.a0;
}

static void guest_main(uint64_t target_cpu)
Expand Down
22 changes: 22 additions & 0 deletions tools/testing/selftests/kvm/include/aarch64/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,26 @@ static inline void local_irq_disable(void)
asm volatile("msr daifset, #3" : : : "memory");
}

/**
* struct arm_smccc_res - Result from SMC/HVC call
* @a0-a3 result values from registers 0 to 3
*/
struct arm_smccc_res {
unsigned long a0;
unsigned long a1;
unsigned long a2;
unsigned long a3;
};

/**
* smccc_hvc - Invoke a SMCCC function using the hvc conduit
* @function_id: the SMCCC function to be called
* @arg0-arg6: SMCCC function arguments, corresponding to registers x1-x7
* @res: pointer to write the return values from registers x0-x3
*
*/
void smccc_hvc(uint32_t function_id, uint64_t arg0, uint64_t arg1,
uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5,
uint64_t arg6, struct arm_smccc_res *res);

#endif /* SELFTEST_KVM_PROCESSOR_H */
25 changes: 25 additions & 0 deletions tools/testing/selftests/kvm/lib/aarch64/processor.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,3 +500,28 @@ void __attribute__((constructor)) init_guest_modes(void)
{
guest_modes_append_default();
}

void smccc_hvc(uint32_t function_id, uint64_t arg0, uint64_t arg1,
uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5,
uint64_t arg6, struct arm_smccc_res *res)
{
asm volatile("mov w0, %w[function_id]\n"
"mov x1, %[arg0]\n"
"mov x2, %[arg1]\n"
"mov x3, %[arg2]\n"
"mov x4, %[arg3]\n"
"mov x5, %[arg4]\n"
"mov x6, %[arg5]\n"
"mov x7, %[arg6]\n"
"hvc #0\n"
"mov %[res0], x0\n"
"mov %[res1], x1\n"
"mov %[res2], x2\n"
"mov %[res3], x3\n"
: [res0] "=r"(res->a0), [res1] "=r"(res->a1),
[res2] "=r"(res->a2), [res3] "=r"(res->a3)
: [function_id] "r"(function_id), [arg0] "r"(arg0),
[arg1] "r"(arg1), [arg2] "r"(arg2), [arg3] "r"(arg3),
[arg4] "r"(arg4), [arg5] "r"(arg5), [arg6] "r"(arg6)
: "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7");
}
13 changes: 3 additions & 10 deletions tools/testing/selftests/kvm/steal_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,17 +118,10 @@ struct st_time {

static int64_t smccc(uint32_t func, uint64_t arg)
{
unsigned long ret;
struct arm_smccc_res res;

asm volatile(
"mov w0, %w1\n"
"mov x1, %2\n"
"hvc #0\n"
"mov %0, x0\n"
: "=r" (ret) : "r" (func), "r" (arg) :
"x0", "x1", "x2", "x3");

return ret;
smccc_hvc(func, arg, 0, 0, 0, 0, 0, 0, &res);
return res.a0;
}

static void check_status(struct st_time *st)
Expand Down

0 comments on commit e918e2b

Please sign in to comment.