[PATCH] target/riscv/kvm: Fix exposure of Zkr
Alistair Francis
alistair23 at gmail.com
Tue Apr 23 17:13:34 PDT 2024
On Mon, Apr 22, 2024 at 11:47 PM Andrew Jones <ajones at ventanamicro.com> wrote:
>
> The Zkr extension may only be exposed to KVM guests if the VMM
> implements the SEED CSR. Use the same implementation as TCG.
>
> Without this patch, running with a KVM which does not forward the
> SEED CSR access to QEMU will result in an ILL exception being
> injected into the guest (this results in Linux guests crashing on
> boot). And, when running with a KVM which does forward the access,
> QEMU will crash, since QEMU doesn't know what to do with the exit.
>
> Fixes: 3108e2f1c69d ("target/riscv/kvm: update KVM exts to Linux 6.8")
> Signed-off-by: Andrew Jones <ajones at ventanamicro.com>
Thanks!
Applied to riscv-to-apply.next
Alistair
> ---
> target/riscv/cpu.h | 3 +++
> target/riscv/csr.c | 18 ++++++++++++++----
> target/riscv/kvm/kvm-cpu.c | 25 +++++++++++++++++++++++++
> 3 files changed, 42 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 3b1a02b9449a..52fb8c15d08f 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -821,6 +821,9 @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
>
> void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
>
> +target_ulong riscv_new_csr_seed(target_ulong new_value,
> + target_ulong write_mask);
> +
> uint8_t satp_mode_max_from_map(uint32_t map);
> const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 726096444fae..829d8346ed4e 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -4267,10 +4267,8 @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
> #endif
>
> /* Crypto Extension */
> -static RISCVException rmw_seed(CPURISCVState *env, int csrno,
> - target_ulong *ret_value,
> - target_ulong new_value,
> - target_ulong write_mask)
> +target_ulong riscv_new_csr_seed(target_ulong new_value,
> + target_ulong write_mask)
> {
> uint16_t random_v;
> Error *random_e = NULL;
> @@ -4294,6 +4292,18 @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
> rval = random_v | SEED_OPST_ES16;
> }
>
> + return rval;
> +}
> +
> +static RISCVException rmw_seed(CPURISCVState *env, int csrno,
> + target_ulong *ret_value,
> + target_ulong new_value,
> + target_ulong write_mask)
> +{
> + target_ulong rval;
> +
> + rval = riscv_new_csr_seed(new_value, write_mask);
> +
> if (ret_value) {
> *ret_value = rval;
> }
> diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
> index 6a6c6cae80f1..50bdbd24a878 100644
> --- a/target/riscv/kvm/kvm-cpu.c
> +++ b/target/riscv/kvm/kvm-cpu.c
> @@ -1418,6 +1418,28 @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
> return ret;
> }
>
> +static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run)
> +{
> + target_ulong csr_num = run->riscv_csr.csr_num;
> + target_ulong new_value = run->riscv_csr.new_value;
> + target_ulong write_mask = run->riscv_csr.write_mask;
> + int ret = 0;
> +
> + switch (csr_num) {
> + case CSR_SEED:
> + run->riscv_csr.ret_value = riscv_new_csr_seed(new_value, write_mask);
> + break;
> + default:
> + qemu_log_mask(LOG_UNIMP,
> + "%s: un-handled CSR EXIT for CSR %lx\n",
> + __func__, csr_num);
> + ret = -1;
> + break;
> + }
> +
> + return ret;
> +}
> +
> int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
> {
> int ret = 0;
> @@ -1425,6 +1447,9 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
> case KVM_EXIT_RISCV_SBI:
> ret = kvm_riscv_handle_sbi(cs, run);
> break;
> + case KVM_EXIT_RISCV_CSR:
> + ret = kvm_riscv_handle_csr(cs, run);
> + break;
> default:
> qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
> __func__, run->exit_reason);
> --
> 2.44.0
>
>
More information about the kvm-riscv
mailing list