On Fri, Aug 02, 2019 at 10:11:38AM +0000, Alexandru Elisei wrote:
> These are the changes that I made to kvm-unit-tests (the diff can be applied
> on
> top of upstream master, 2130fd4154ad ("tscdeadline_latency: Check condition
> first before loop")):
It's great to hear that you're doing this. You may find these bit-rotted
commits useful too
https://github.com/rhdrjones/kvm-unit-tests/commits/arm64/hyp-mode
Thanks,
drew
>
> diff --git a/arm/cstart64.S b/arm/cstart64.S
> index b0e8baa1a23a..a7631b5a1801 100644
> --- a/arm/cstart64.S
> +++ b/arm/cstart64.S
> @@ -51,6 +51,17 @@ start:
> b 1b
>
> 1:
> + mrs x4, CurrentEL
> + cmp x4, CurrentEL_EL2
> + b.ne 1f
> + mrs x4, mpidr_el1
> + msr vmpidr_el2, x4
> + mrs x4, midr_el1
> + msr vpidr_el2, x4
> + ldr x4, =(HCR_EL2_TGE | HCR_EL2_E2H)
> + msr hcr_el2, x4
> + isb
> +1:
> /* set up stack */
> mov x4, #1
> msr spsel, x4
> @@ -101,6 +112,17 @@ get_mmu_off:
>
> .globl secondary_entry
> secondary_entry:
> + mrs x0, CurrentEL
> + cmp x0, CurrentEL_EL2
> + b.ne 1f
> + mrs x0, mpidr_el1
> + msr vmpidr_el2, x0
> + mrs x0, midr_el1
> + msr vpidr_el2, x0
> + ldr x0, =(HCR_EL2_TGE | HCR_EL2_E2H)
> + msr hcr_el2, x0
> + isb
> +1:
> /* Enable FP/ASIMD */
> mov x0, #(3 << 20)
> msr cpacr_el1, x0
> diff --git a/lib/arm/asm/psci.h b/lib/arm/asm/psci.h
> index 7b956bf5987d..07297a27e0ce 100644
> --- a/lib/arm/asm/psci.h
> +++ b/lib/arm/asm/psci.h
> @@ -3,6 +3,15 @@
> #include <libcflat.h>
> #include <linux/psci.h>
>
> +enum psci_conduit {
> + PSCI_CONDUIT_HVC,
> + PSCI_CONDUIT_SMC,
> +};
> +
> +extern void psci_init(void);
> +extern void psci_set_conduit(enum psci_conduit conduit);
> +extern enum psci_conduit psci_get_conduit(void);
> +
> extern int psci_invoke(unsigned long function_id, unsigned long arg0,
> unsigned long arg1, unsigned long arg2);
> extern int psci_cpu_on(unsigned long cpuid, unsigned long entry_point);
> diff --git a/lib/arm/psci.c b/lib/arm/psci.c
> index c3d399064ae3..20ad4b944738 100644
> --- a/lib/arm/psci.c
> +++ b/lib/arm/psci.c
> @@ -6,13 +6,14 @@
> *
> * This work is licensed under the terms of the GNU LGPL, version 2.
> */
> +#include <devicetree.h>
> +#include <string.h>
> #include <asm/psci.h>
> #include <asm/setup.h>
> #include <asm/page.h>
> #include <asm/smp.h>
>
> -__attribute__((noinline))
> -int psci_invoke(unsigned long function_id, unsigned long arg0,
> +static int psci_invoke_hvc(unsigned long function_id, unsigned long arg0,
> unsigned long arg1, unsigned long arg2)
> {
> asm volatile(
> @@ -22,6 +23,63 @@ int psci_invoke(unsigned long function_id, unsigned long
> arg0,
> return function_id;
> }
>
> +static int psci_invoke_smc(unsigned long function_id, unsigned long arg0,
> + unsigned long arg1, unsigned long arg2)
> +{
> + asm volatile(
> + "smc #0"
> + : "+r" (function_id)
> + : "r" (arg0), "r" (arg1), "r" (arg2));
> + return function_id;
> +}
> +
> +/*
> + * Initialize to something sensible, so the exit fallback psci_system_off
> still
> + * works before calling psci_init when booted at EL1.
> + */
> +static enum psci_conduit psci_conduit = PSCI_CONDUIT_HVC;
> +static int (*psci_fn)(unsigned long, unsigned long, unsigned long,
> + unsigned long) = &psci_invoke_hvc;
> +
> +void psci_set_conduit(enum psci_conduit conduit)
> +{
> + psci_conduit = conduit;
> + if (conduit == PSCI_CONDUIT_HVC)
> + psci_fn = &psci_invoke_hvc;
> + else
> + psci_fn = &psci_invoke_smc;
> +}
> +
> +enum psci_conduit psci_get_conduit(void)
> +{
> + return psci_conduit;
> +}
> +
> +int psci_invoke(unsigned long function_id, unsigned long arg0,
> + unsigned long arg1, unsigned long arg2)
> +{
> + return psci_fn(function_id, arg0, arg1, arg2);
> +}
> +
> +void psci_init(void)
> +{
> + const char *conduit;
> + int ret;
> +
> + ret = dt_get_psci_conduit(&conduit);
> + assert(ret == 0 || ret == -FDT_ERR_NOTFOUND);
> +
> + if (ret == -FDT_ERR_NOTFOUND)
> + conduit = "hvc";
> +
> + assert(strcmp(conduit, "hvc") == 0 || strcmp(conduit, "smc") == 0);
> +
> + if (strcmp(conduit, "hvc") == 0)
> + psci_set_conduit(PSCI_CONDUIT_HVC);
> + else
> + psci_set_conduit(PSCI_CONDUIT_SMC);
> +}
> +
> int psci_cpu_on(unsigned long cpuid, unsigned long entry_point)
> {
> #ifdef __arm__
> diff --git a/lib/arm/setup.c b/lib/arm/setup.c
> index 4f02fca85607..e0dc9e4801b0 100644
> --- a/lib/arm/setup.c
> +++ b/lib/arm/setup.c
> @@ -21,6 +21,7 @@
> #include <asm/setup.h>
> #include <asm/page.h>
> #include <asm/smp.h>
> +#include <asm/psci.h>
>
> #include "io.h"
>
> @@ -164,7 +165,11 @@ void setup(const void *fdt)
> freemem += initrd_size;
> }
>
> - /* call init functions */
> + /*
> + * call init functions. psci_init goes first so psci_system_off
> fallback
> + * works in case of an assert failure
> + */
> + psci_init();
> mem_init(PAGE_ALIGN((unsigned long)freemem));
> cpu_init();
>
> diff --git a/lib/arm64/asm/processor.h b/lib/arm64/asm/processor.h
> index 1d9223f728a5..18c5d29ddd1f 100644
> --- a/lib/arm64/asm/processor.h
> +++ b/lib/arm64/asm/processor.h
> @@ -16,6 +16,9 @@
> #define SCTLR_EL1_A (1 << 1)
> #define SCTLR_EL1_M (1 << 0)
>
> +#define HCR_EL2_TGE (1 << 27)
> +#define HCR_EL2_E2H (1 << 34)
> +
> #ifndef __ASSEMBLY__
> #include <asm/ptrace.h>
> #include <asm/esr.h>
> diff --git a/lib/devicetree.c b/lib/devicetree.c
> index 2b89178a109b..4e684c7100b2 100644
> --- a/lib/devicetree.c
> +++ b/lib/devicetree.c
> @@ -263,6 +263,27 @@ int dt_get_bootargs(const char **bootargs)
> return 0;
> }
>
> +int dt_get_psci_conduit(const char **conduit)
> +{
> + const struct fdt_property *prop;
> + int node, len;
> +
> + *conduit = NULL;
> +
> + node = fdt_node_offset_by_compatible(fdt, -1, "arm,psci-0.2");
> + if (node < 0)
> + return node;
> +
> + prop = fdt_get_property(fdt, node, "method", &len);
> + if (!prop)
> + return len;
> + if (len < 4)
> + return -FDT_ERR_NOTFOUND;
> +
> + *conduit = prop->data;
> + return 0;
> +}
> +
> int dt_get_default_console_node(void)
> {
> const struct fdt_property *prop;
> diff --git a/lib/devicetree.h b/lib/devicetree.h
> index 93c7ebc63bd8..236035eb777d 100644
> --- a/lib/devicetree.h
> +++ b/lib/devicetree.h
> @@ -211,6 +211,15 @@ extern int dt_get_reg(int fdtnode, int regidx, struct
> dt_reg *reg);
> extern int dt_get_bootargs(const char **bootargs);
>
> /*
> + * dt_get_psci_conduit gets the conduit for PSCI function invocations from
> + * /psci/method
> + * returns
> + * - zero on success
> + * - a negative FDT_ERR_* value on failure, and @conduit will be set to
> null
> + */
> +extern int dt_get_psci_conduit(const char **conduit);
> +
> +/*
> * dt_get_default_console_node gets the node of the path stored in
> * /chosen/stdout-path (or the deprecated /chosen/linux,stdout-path)
> * returns
>
> IMPORTANT NOTICE: The contents of this email and any attachments are
> confidential and may also be privileged. If you are not the intended
> recipient, please notify the sender immediately and do not disclose the
> contents to any other person, use it for any purpose, or store or copy the
> information in any medium. Thank you.
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm