[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <fe2dd7e1-4480-78e0-cfbd-4fc3574c589c@loongson.cn>
Date: Mon, 2 Feb 2026 10:33:25 +0800
From: Bibo Mao <maobibo@...ngson.cn>
To: Zixing Liu <liushuyu@...c.io>, WANG Xuerui <kernel@...0n.name>,
Huacai Chen <chenhuacai@...nel.org>
Cc: Kexy Biscuit <kexybiscuit@...c.io>, Mingcong Bai <jeffbai@...c.io>,
Paolo Bonzini <pbonzini@...hat.com>, Jonathan Corbet <corbet@....net>,
Tianrui Zhao <zhaotianrui@...ngson.cn>, Paul Walmsley <pjw@...nel.org>,
Palmer Dabbelt <palmer@...belt.com>, Albert Ou <aou@...s.berkeley.edu>,
Alexandre Ghiti <alex@...ti.fr>, kvm@...r.kernel.org,
linux-doc@...r.kernel.org, linux-kernel@...r.kernel.org,
loongarch@...ts.linux.dev, linux-riscv@...ts.infradead.org
Subject: Re: [PATCH v3] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch
On 2026/2/1 下午3:21, Zixing Liu wrote:
> This ioctl can be used by the userspace applications to determine which
> (special) registers are get/set-able in a meaningful way.
>
> This can be very useful for cross-platform VMMs so that they do not have
> to hardcode register indices for each supported architectures.
>
> Signed-off-by: Zixing Liu <liushuyu@...c.io>
> ---
> Documentation/virt/kvm/api.rst | 2 +-
> arch/loongarch/kvm/vcpu.c | 81 ++++++++++++++++++++++++++++++++++
> 2 files changed, 82 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
> index 01a3abef8abb..f46dd8be282f 100644
> --- a/Documentation/virt/kvm/api.rst
> +++ b/Documentation/virt/kvm/api.rst
> @@ -3603,7 +3603,7 @@ VCPU matching underlying host.
> ---------------------
>
> :Capability: basic
> -:Architectures: arm64, mips, riscv, x86 (if KVM_CAP_ONE_REG)
> +:Architectures: arm64, loongarch, mips, riscv, x86 (if KVM_CAP_ONE_REG)
> :Type: vcpu ioctl
> :Parameters: struct kvm_reg_list (in/out)
> :Returns: 0 on success; -1 on error
> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
> index 656b954c1134..fb8001deadc9 100644
> --- a/arch/loongarch/kvm/vcpu.c
> +++ b/arch/loongarch/kvm/vcpu.c
> @@ -14,6 +14,8 @@
> #define CREATE_TRACE_POINTS
> #include "trace.h"
>
> +#define NUM_LBT_REGS 6
> +
> const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
> KVM_GENERIC_VCPU_STATS(),
> STATS_DESC_COUNTER(VCPU, int_exits),
> @@ -1186,6 +1188,67 @@ static int kvm_loongarch_vcpu_set_attr(struct kvm_vcpu *vcpu,
> return ret;
> }
>
> +static int kvm_loongarch_walk_csrs(struct kvm_vcpu *vcpu, u64 __user *uindices)
> +{
> + unsigned int i, count;
> +
> + for (i = 0, count = 0; i < CSR_MAX_NUMS; i++) {
> + if (!(get_gcsr_flag(i) & (SW_GCSR | HW_GCSR)))
My main concern is how to use KVM_GET_REG_LIST ioctl command, there will
be compatible issue if the detail use scenery about KVM_GET_REG_LIST
command is not clear.
Can KVM_GET_REG_LIST ioctl command be used before vCPU feature
finalized? If not, it is only used after vCPU feature finalized, guest
CSR registers should base on vCPU features rather than host features.
Here get_gcsr_flag() is based on host features.
Regards
Bibo Mao
> + continue;
> + const u64 reg = KVM_IOC_CSRID(i);
> + if (uindices && put_user(reg, uindices++))
> + return -EFAULT;
> + count++;
> + }
> +
> + return count;
> +}
> +
> +static unsigned long kvm_loongarch_num_regs(struct kvm_vcpu *vcpu)
> +{
> + /* +1 for the KVM_REG_LOONGARCH_COUNTER register */
> + unsigned long res =
> + kvm_loongarch_walk_csrs(vcpu, NULL) + KVM_MAX_CPUCFG_REGS + 1;
> +
> + if (kvm_guest_has_lbt(&vcpu->arch))
> + res += NUM_LBT_REGS;
> +
> + return res;
> +}
> +
> +static int kvm_loongarch_copy_reg_indices(struct kvm_vcpu *vcpu,
> + u64 __user *uindices)
> +{
> + u64 reg;
> + unsigned int i;
> +
> + i = kvm_loongarch_walk_csrs(vcpu, uindices);
> + if (i < 0)
> + return i;
> + uindices += i;
> +
> + for (i = 0; i < KVM_MAX_CPUCFG_REGS; i++) {
> + reg = KVM_IOC_CPUCFG(i);
> + if (put_user(reg, uindices++))
> + return -EFAULT;
> + }
> +
> + reg = KVM_REG_LOONGARCH_COUNTER;
> + if (put_user(reg, uindices++))
> + return -EFAULT;
> +
> + if (!kvm_guest_has_lbt(&vcpu->arch))
> + return 0;
> +
> + for (i = 1; i <= NUM_LBT_REGS; i++) {
> + reg = (KVM_REG_LOONGARCH_LBT | KVM_REG_SIZE_U64 | i);
> + if (put_user(reg, uindices++))
> + return -EFAULT;
> + }
> +
> + return 0;
> +}
> +
> long kvm_arch_vcpu_ioctl(struct file *filp,
> unsigned int ioctl, unsigned long arg)
> {
> @@ -1251,6 +1314,24 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
> r = kvm_loongarch_vcpu_set_attr(vcpu, &attr);
> break;
> }
> + case KVM_GET_REG_LIST: {
> + struct kvm_reg_list __user *user_list = argp;
> + struct kvm_reg_list reg_list;
> + unsigned n;
> +
> + r = -EFAULT;
> + if (copy_from_user(®_list, user_list, sizeof(reg_list)))
> + break;
> + n = reg_list.n;
> + reg_list.n = kvm_loongarch_num_regs(vcpu);
> + if (copy_to_user(user_list, ®_list, sizeof(reg_list)))
> + break;
> + r = -E2BIG;
> + if (n < reg_list.n)
> + break;
> + r = kvm_loongarch_copy_reg_indices(vcpu, user_list->reg);
> + break;
> + }
> default:
> r = -ENOIOCTLCMD;
> break;
>
Powered by blists - more mailing lists