qemu-riscv
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] target/riscv/kvm: implement SBI debug console (DBCN) calls


From: Alistair Francis
Subject: Re: [PATCH] target/riscv/kvm: implement SBI debug console (DBCN) calls
Date: Mon, 29 Apr 2024 12:23:25 +1000

On Fri, Apr 26, 2024 at 1:51 AM Daniel Henrique Barboza
<dbarboza@ventanamicro.com> wrote:
>
> SBI defines a Debug Console extension "DBCN" that will, in time, replace
> the legacy console putchar and getchar SBI extensions.
>
> The appeal of the DBCN extension is that it allows multiple bytes to be
> read/written in the SBI console in a single SBI call.
>
> As far as KVM goes, the DBCN calls are forwarded by an in-kernel KVM
> module to userspace. But this will only happens if the KVM module
> actually supports this SBI extension and we activate it.
>
> We'll check for DBCN support during init time, checking if get-reg-list
> is advertising KVM_RISCV_SBI_EXT_DBCN. In that case, we'll enable it via
> kvm_set_one_reg() during kvm_arch_init_vcpu().
>
> Finally, change kvm_riscv_handle_sbi() to handle the incoming calls for
> SBI_EXT_DBCN, reading and writing as required.
>
> A simple KVM guest with 'earlycon=sbi', running in an emulated RISC-V
> host, takes around 20 seconds to boot without using DBCN. With this
> patch we're taking around 14 seconds to boot due to the speed-up in the
> terminal output.  There's no change in boot time if the guest isn't
> using earlycon.
>
> Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>

Thanks!

Applied to riscv-to-apply.next

Alistair

> ---
>  target/riscv/kvm/kvm-cpu.c         | 111 +++++++++++++++++++++++++++++
>  target/riscv/sbi_ecall_interface.h |  17 +++++
>  2 files changed, 128 insertions(+)
>
> diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
> index 03e3fee607..54a9ab9fd7 100644
> --- a/target/riscv/kvm/kvm-cpu.c
> +++ b/target/riscv/kvm/kvm-cpu.c
> @@ -409,6 +409,12 @@ static KVMCPUConfig kvm_v_vlenb = {
>                     KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)
>  };
>
> +static KVMCPUConfig kvm_sbi_dbcn = {
> +    .name = "sbi_dbcn",
> +    .kvm_reg_id = KVM_REG_RISCV | KVM_REG_SIZE_U64 |
> +                  KVM_REG_RISCV_SBI_EXT | KVM_RISCV_SBI_EXT_DBCN
> +};
> +
>  static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
>  {
>      CPURISCVState *env = &cpu->env;
> @@ -1041,6 +1047,20 @@ static int uint64_cmp(const void *a, const void *b)
>      return 0;
>  }
>
> +static void kvm_riscv_check_sbi_dbcn_support(RISCVCPU *cpu,
> +                                             KVMScratchCPU *kvmcpu,
> +                                             struct kvm_reg_list *reglist)
> +{
> +    struct kvm_reg_list *reg_search;
> +
> +    reg_search = bsearch(&kvm_sbi_dbcn.kvm_reg_id, reglist->reg, reglist->n,
> +                         sizeof(uint64_t), uint64_cmp);
> +
> +    if (reg_search) {
> +        kvm_sbi_dbcn.supported = true;
> +    }
> +}
> +
>  static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
>                                   struct kvm_reg_list *reglist)
>  {
> @@ -1146,6 +1166,8 @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, 
> KVMScratchCPU *kvmcpu)
>      if (riscv_has_ext(&cpu->env, RVV)) {
>          kvm_riscv_read_vlenb(cpu, kvmcpu, reglist);
>      }
> +
> +    kvm_riscv_check_sbi_dbcn_support(cpu, kvmcpu, reglist);
>  }
>
>  static void riscv_init_kvm_registers(Object *cpu_obj)
> @@ -1320,6 +1342,17 @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, 
> CPUState *cs)
>      return ret;
>  }
>
> +static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs)
> +{
> +    target_ulong reg = 1;
> +
> +    if (!kvm_sbi_dbcn.supported) {
> +        return 0;
> +    }
> +
> +    return kvm_set_one_reg(cs, kvm_sbi_dbcn.kvm_reg_id, &reg);
> +}
> +
>  int kvm_arch_init_vcpu(CPUState *cs)
>  {
>      int ret = 0;
> @@ -1337,6 +1370,8 @@ int kvm_arch_init_vcpu(CPUState *cs)
>      kvm_riscv_update_cpu_misa_ext(cpu, cs);
>      kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
>
> +    ret = kvm_vcpu_enable_sbi_dbcn(cpu, cs);
> +
>      return ret;
>  }
>
> @@ -1394,6 +1429,79 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
>      return true;
>  }
>
> +static void kvm_riscv_handle_sbi_dbcn(CPUState *cs, struct kvm_run *run)
> +{
> +    g_autofree uint8_t *buf = NULL;
> +    RISCVCPU *cpu = RISCV_CPU(cs);
> +    target_ulong num_bytes;
> +    uint64_t addr;
> +    unsigned char ch;
> +    int ret;
> +
> +    switch (run->riscv_sbi.function_id) {
> +    case SBI_EXT_DBCN_CONSOLE_READ:
> +    case SBI_EXT_DBCN_CONSOLE_WRITE:
> +        num_bytes = run->riscv_sbi.args[0];
> +
> +        if (num_bytes == 0) {
> +            run->riscv_sbi.ret[0] = SBI_SUCCESS;
> +            run->riscv_sbi.ret[1] = 0;
> +            break;
> +        }
> +
> +        addr = run->riscv_sbi.args[1];
> +
> +        /*
> +         * Handle the case where a 32 bit CPU is running in a
> +         * 64 bit addressing env.
> +         */
> +        if (riscv_cpu_mxl(&cpu->env) == MXL_RV32) {
> +            addr |= (uint64_t)run->riscv_sbi.args[2] << 32;
> +        }
> +
> +        buf = g_malloc0(num_bytes);
> +
> +        if (run->riscv_sbi.function_id == SBI_EXT_DBCN_CONSOLE_READ) {
> +            ret = qemu_chr_fe_read_all(serial_hd(0)->be, buf, num_bytes);
> +            if (ret < 0) {
> +                error_report("SBI_EXT_DBCN_CONSOLE_READ: error when "
> +                             "reading chardev");
> +                exit(1);
> +            }
> +
> +            cpu_physical_memory_write(addr, buf, ret);
> +        } else {
> +            cpu_physical_memory_read(addr, buf, num_bytes);
> +
> +            ret = qemu_chr_fe_write_all(serial_hd(0)->be, buf, num_bytes);
> +            if (ret < 0) {
> +                error_report("SBI_EXT_DBCN_CONSOLE_WRITE: error when "
> +                             "writing chardev");
> +                exit(1);
> +            }
> +        }
> +
> +        run->riscv_sbi.ret[0] = SBI_SUCCESS;
> +        run->riscv_sbi.ret[1] = ret;
> +        break;
> +    case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
> +        ch = run->riscv_sbi.args[0];
> +        ret = qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
> +
> +        if (ret < 0) {
> +            error_report("SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: error when "
> +                         "writing chardev");
> +            exit(1);
> +        }
> +
> +        run->riscv_sbi.ret[0] = SBI_SUCCESS;
> +        run->riscv_sbi.ret[1] = 0;
> +        break;
> +    default:
> +        run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED;
> +    }
> +}
> +
>  static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
>  {
>      int ret = 0;
> @@ -1412,6 +1520,9 @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct 
> kvm_run *run)
>          }
>          ret = 0;
>          break;
> +    case SBI_EXT_DBCN:
> +        kvm_riscv_handle_sbi_dbcn(cs, run);
> +        break;
>      default:
>          qemu_log_mask(LOG_UNIMP,
>                        "%s: un-handled SBI EXIT, specific reasons is %lu\n",
> diff --git a/target/riscv/sbi_ecall_interface.h 
> b/target/riscv/sbi_ecall_interface.h
> index 43899d08f6..7dfe5f72c6 100644
> --- a/target/riscv/sbi_ecall_interface.h
> +++ b/target/riscv/sbi_ecall_interface.h
> @@ -12,6 +12,17 @@
>
>  /* clang-format off */
>
> +#define SBI_SUCCESS                      0
> +#define SBI_ERR_FAILED                  -1
> +#define SBI_ERR_NOT_SUPPORTED           -2
> +#define SBI_ERR_INVALID_PARAM           -3
> +#define SBI_ERR_DENIED                  -4
> +#define SBI_ERR_INVALID_ADDRESS         -5
> +#define SBI_ERR_ALREADY_AVAILABLE       -6
> +#define SBI_ERR_ALREADY_STARTED         -7
> +#define SBI_ERR_ALREADY_STOPPED         -8
> +#define SBI_ERR_NO_SHMEM                -9
> +
>  /* SBI Extension IDs */
>  #define SBI_EXT_0_1_SET_TIMER           0x0
>  #define SBI_EXT_0_1_CONSOLE_PUTCHAR     0x1
> @@ -27,6 +38,7 @@
>  #define SBI_EXT_IPI                     0x735049
>  #define SBI_EXT_RFENCE                  0x52464E43
>  #define SBI_EXT_HSM                     0x48534D
> +#define SBI_EXT_DBCN                    0x4442434E
>
>  /* SBI function IDs for BASE extension */
>  #define SBI_EXT_BASE_GET_SPEC_VERSION   0x0
> @@ -57,6 +69,11 @@
>  #define SBI_EXT_HSM_HART_STOP           0x1
>  #define SBI_EXT_HSM_HART_GET_STATUS     0x2
>
> +/* SBI function IDs for DBCN extension */
> +#define SBI_EXT_DBCN_CONSOLE_WRITE      0x0
> +#define SBI_EXT_DBCN_CONSOLE_READ       0x1
> +#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE 0x2
> +
>  #define SBI_HSM_HART_STATUS_STARTED     0x0
>  #define SBI_HSM_HART_STATUS_STOPPED     0x1
>  #define SBI_HSM_HART_STATUS_START_PENDING   0x2
> --
> 2.44.0
>
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]