diff mbox series

target/arm: Report KVM's actual PSCI version to guest in dtb

Message ID 20220224134655.1207865-1-peter.maydell@linaro.org
State New
Headers show
Series target/arm: Report KVM's actual PSCI version to guest in dtb | expand

Commit Message

Peter Maydell Feb. 24, 2022, 1:46 p.m. UTC
When we're using KVM, the PSCI implementation is provided by the
kernel, but QEMU has to tell the guest about it via the device tree.
Currently we look at the KVM_CAP_ARM_PSCI_0_2 capability to determine
if the kernel is providing at least PSCI 0.2, but if the kernel
provides a newer version than that we will still only tell the guest
it has PSCI 0.2.  (This is fairly harmless; it just means the guest
won't use newer parts of the PSCI API.)

The kernel exposes the specific PSCI version it is implementing via
the ONE_REG API; use this to report in the dtb that the PSCI
implementation is 1.0-compatible if appropriate.  (The device tree
binding currently only distinguishes "pre-0.2", "0.2-compatible" and
"1.0-compatible".)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
Based-on: 20220213035753.34577-1-akihiko.odaki@gmail.com
("[PATCH v2] target/arm: Support PSCI 1.1 and SMCCC 1.0")
though note that to compile on arm hosts you'll need the
bugfix to that patch from which I describe in a reply to it.

 target/arm/kvm-consts.h |  1 +
 hw/arm/boot.c           |  5 ++---
 target/arm/kvm64.c      | 12 ++++++++++++
 3 files changed, 15 insertions(+), 3 deletions(-)

Comments

Akihiko Odaki Feb. 24, 2022, 3 p.m. UTC | #1
Reviewed-by: Akihiko Odaki <akihiko.odaki@gmail.com>

On Thu, Feb 24, 2022 at 10:46 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> When we're using KVM, the PSCI implementation is provided by the
> kernel, but QEMU has to tell the guest about it via the device tree.
> Currently we look at the KVM_CAP_ARM_PSCI_0_2 capability to determine
> if the kernel is providing at least PSCI 0.2, but if the kernel
> provides a newer version than that we will still only tell the guest
> it has PSCI 0.2.  (This is fairly harmless; it just means the guest
> won't use newer parts of the PSCI API.)
>
> The kernel exposes the specific PSCI version it is implementing via
> the ONE_REG API; use this to report in the dtb that the PSCI
> implementation is 1.0-compatible if appropriate.  (The device tree
> binding currently only distinguishes "pre-0.2", "0.2-compatible" and
> "1.0-compatible".)
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> Based-on: 20220213035753.34577-1-akihiko.odaki@gmail.com
> ("[PATCH v2] target/arm: Support PSCI 1.1 and SMCCC 1.0")
> though note that to compile on arm hosts you'll need the
> bugfix to that patch from which I describe in a reply to it.
>
>  target/arm/kvm-consts.h |  1 +
>  hw/arm/boot.c           |  5 ++---
>  target/arm/kvm64.c      | 12 ++++++++++++
>  3 files changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
> index e770921ddc2..faacf96fdc7 100644
> --- a/target/arm/kvm-consts.h
> +++ b/target/arm/kvm-consts.h
> @@ -95,6 +95,7 @@ MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES);
>
>  #define QEMU_PSCI_VERSION_0_1                     0x00001
>  #define QEMU_PSCI_VERSION_0_2                     0x00002
> +#define QEMU_PSCI_VERSION_1_0                     0x10000
>  #define QEMU_PSCI_VERSION_1_1                     0x10001
>
>  MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP);
> diff --git a/hw/arm/boot.c b/hw/arm/boot.c
> index 0eeef94ceb5..a47f38dfc90 100644
> --- a/hw/arm/boot.c
> +++ b/hw/arm/boot.c
> @@ -488,9 +488,8 @@ static void fdt_add_psci_node(void *fdt)
>      }
>
>      qemu_fdt_add_subnode(fdt, "/psci");
> -    if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
> -        armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
> -        if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) {
> +    if (armcpu->psci_version >= QEMU_PSCI_VERSION_0_2) {
> +        if (armcpu->psci_version < QEMU_PSCI_VERSION_1_0) {
>              const char comp[] = "arm,psci-0.2\0arm,psci";
>              qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
>          } else {
> diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
> index 64d48bfb19d..ccadfbbe72b 100644
> --- a/target/arm/kvm64.c
> +++ b/target/arm/kvm64.c
> @@ -849,6 +849,7 @@ int kvm_arch_init_vcpu(CPUState *cs)
>      uint64_t mpidr;
>      ARMCPU *cpu = ARM_CPU(cs);
>      CPUARMState *env = &cpu->env;
> +    uint64_t psciver;
>
>      if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
>          !object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) {
> @@ -904,6 +905,17 @@ int kvm_arch_init_vcpu(CPUState *cs)
>          }
>      }
>
> +    /*
> +     * KVM reports the exact PSCI version it is implementing via a
> +     * special sysreg. If it is present, use its contents to determine
> +     * what to report to the guest in the dtb (it is the PSCI version,
> +     * in the same 15-bits major 16-bits minor format that PSCI_VERSION
> +     * returns).
> +     */
> +    if (!kvm_get_one_reg(cs, KVM_REG_ARM_PSCI_VERSION, &psciver)) {
> +        cpu->psci_version = psciver;
> +    }
> +
>      /*
>       * When KVM is in use, PSCI is emulated in-kernel and not by qemu.
>       * Currently KVM has its own idea about MPIDR assignment, so we
> --
> 2.25.1
>
Richard Henderson Feb. 24, 2022, 6:19 p.m. UTC | #2
On 2/24/22 03:46, Peter Maydell wrote:
> When we're using KVM, the PSCI implementation is provided by the
> kernel, but QEMU has to tell the guest about it via the device tree.
> Currently we look at the KVM_CAP_ARM_PSCI_0_2 capability to determine
> if the kernel is providing at least PSCI 0.2, but if the kernel
> provides a newer version than that we will still only tell the guest
> it has PSCI 0.2.  (This is fairly harmless; it just means the guest
> won't use newer parts of the PSCI API.)
> 
> The kernel exposes the specific PSCI version it is implementing via
> the ONE_REG API; use this to report in the dtb that the PSCI
> implementation is 1.0-compatible if appropriate.  (The device tree
> binding currently only distinguishes "pre-0.2", "0.2-compatible" and
> "1.0-compatible".)
> 
> Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
> ---
> Based-on:20220213035753.34577-1-akihiko.odaki@gmail.com
> ("[PATCH v2] target/arm: Support PSCI 1.1 and SMCCC 1.0")
> though note that to compile on arm hosts you'll need the
> bugfix to that patch from which I describe in a reply to it.
> 
>   target/arm/kvm-consts.h |  1 +
>   hw/arm/boot.c           |  5 ++---
>   target/arm/kvm64.c      | 12 ++++++++++++
>   3 files changed, 15 insertions(+), 3 deletions(-)

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

r~
Andrew Jones Feb. 28, 2022, 12:20 p.m. UTC | #3
On Thu, Feb 24, 2022 at 01:46:54PM +0000, Peter Maydell wrote:
> When we're using KVM, the PSCI implementation is provided by the
> kernel, but QEMU has to tell the guest about it via the device tree.
> Currently we look at the KVM_CAP_ARM_PSCI_0_2 capability to determine
> if the kernel is providing at least PSCI 0.2, but if the kernel
> provides a newer version than that we will still only tell the guest
> it has PSCI 0.2.  (This is fairly harmless; it just means the guest
> won't use newer parts of the PSCI API.)
> 
> The kernel exposes the specific PSCI version it is implementing via
> the ONE_REG API; use this to report in the dtb that the PSCI
> implementation is 1.0-compatible if appropriate.  (The device tree
> binding currently only distinguishes "pre-0.2", "0.2-compatible" and
> "1.0-compatible".)
> 
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
> Based-on: 20220213035753.34577-1-akihiko.odaki@gmail.com
> ("[PATCH v2] target/arm: Support PSCI 1.1 and SMCCC 1.0")
> though note that to compile on arm hosts you'll need the
> bugfix to that patch from which I describe in a reply to it.
> 
>  target/arm/kvm-consts.h |  1 +
>  hw/arm/boot.c           |  5 ++---
>  target/arm/kvm64.c      | 12 ++++++++++++
>  3 files changed, 15 insertions(+), 3 deletions(-)
>

Reviewed-by: Andrew Jones <drjones@redhat.com>
diff mbox series

Patch

diff --git a/target/arm/kvm-consts.h b/target/arm/kvm-consts.h
index e770921ddc2..faacf96fdc7 100644
--- a/target/arm/kvm-consts.h
+++ b/target/arm/kvm-consts.h
@@ -95,6 +95,7 @@  MISMATCH_CHECK(QEMU_PSCI_1_0_FN_PSCI_FEATURES, PSCI_1_0_FN_PSCI_FEATURES);
 
 #define QEMU_PSCI_VERSION_0_1                     0x00001
 #define QEMU_PSCI_VERSION_0_2                     0x00002
+#define QEMU_PSCI_VERSION_1_0                     0x10000
 #define QEMU_PSCI_VERSION_1_1                     0x10001
 
 MISMATCH_CHECK(QEMU_PSCI_0_2_RET_TOS_MIGRATION_NOT_REQUIRED, PSCI_0_2_TOS_MP);
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 0eeef94ceb5..a47f38dfc90 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -488,9 +488,8 @@  static void fdt_add_psci_node(void *fdt)
     }
 
     qemu_fdt_add_subnode(fdt, "/psci");
-    if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2 ||
-        armcpu->psci_version == QEMU_PSCI_VERSION_1_1) {
-        if (armcpu->psci_version == QEMU_PSCI_VERSION_0_2) {
+    if (armcpu->psci_version >= QEMU_PSCI_VERSION_0_2) {
+        if (armcpu->psci_version < QEMU_PSCI_VERSION_1_0) {
             const char comp[] = "arm,psci-0.2\0arm,psci";
             qemu_fdt_setprop(fdt, "/psci", "compatible", comp, sizeof(comp));
         } else {
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
index 64d48bfb19d..ccadfbbe72b 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -849,6 +849,7 @@  int kvm_arch_init_vcpu(CPUState *cs)
     uint64_t mpidr;
     ARMCPU *cpu = ARM_CPU(cs);
     CPUARMState *env = &cpu->env;
+    uint64_t psciver;
 
     if (cpu->kvm_target == QEMU_KVM_ARM_TARGET_NONE ||
         !object_dynamic_cast(OBJECT(cpu), TYPE_AARCH64_CPU)) {
@@ -904,6 +905,17 @@  int kvm_arch_init_vcpu(CPUState *cs)
         }
     }
 
+    /*
+     * KVM reports the exact PSCI version it is implementing via a
+     * special sysreg. If it is present, use its contents to determine
+     * what to report to the guest in the dtb (it is the PSCI version,
+     * in the same 15-bits major 16-bits minor format that PSCI_VERSION
+     * returns).
+     */
+    if (!kvm_get_one_reg(cs, KVM_REG_ARM_PSCI_VERSION, &psciver)) {
+        cpu->psci_version = psciver;
+    }
+
     /*
      * When KVM is in use, PSCI is emulated in-kernel and not by qemu.
      * Currently KVM has its own idea about MPIDR assignment, so we