[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <29565e27-f153-c2c5-cbc3-e0457d45f094@loongson.cn>
Date: Mon, 26 Jan 2026 11:57:31 +0800
From: Bibo Mao <maobibo@...ngson.cn>
To: liushuyu <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>, Miguel Ojeda <ojeda@...nel.org>,
Boqun Feng <boqun.feng@...il.com>, Gary Guo <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>,
Benno Lossin <lossin@...nel.org>, Andreas Hindborg <a.hindborg@...nel.org>,
Alice Ryhl <aliceryhl@...gle.com>, Trevor Gross <tmgross@...ch.edu>,
Danilo Krummrich <dakr@...nel.org>, kvm@...r.kernel.org,
linux-doc@...r.kernel.org, linux-kernel@...r.kernel.org,
loongarch@...ts.linux.dev, linux-riscv@...ts.infradead.org,
rust-for-linux@...r.kernel.org
Subject: Re: [PATCH 1/1] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch
On 2026/1/26 上午11:38, liushuyu wrote:
> Hi Bibo,
>>
>>
>> On 2026/1/25 下午1:43, Zixing Liu wrote:
>>> This ioctl can be used by userspace applications to determine which
>>> (special) registers are get/set-able.
>>>
>>> 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>
>>> ---
>>>
>>> For example, this ioctl could be used by rust-vmm/rust-kvm or maybe
>>> VirtualBox-kvm in the future.
>>>
>>> Documentation/virt/kvm/api.rst | 2 +-
>>> arch/loongarch/kvm/vcpu.c | 69 ++++++++++++++++++++++++++++++++++
>>> 2 files changed, 70 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..b884eb9c76aa 100644
>>> --- a/arch/loongarch/kvm/vcpu.c
>>> +++ b/arch/loongarch/kvm/vcpu.c
>>> @@ -1186,6 +1186,57 @@ static int kvm_loongarch_vcpu_set_attr(struct
>>> kvm_vcpu *vcpu,
>>> return ret;
>>> }
>>> +static unsigned long kvm_loongarch_num_lbt_regs(void)
>>> +{
>>> + /* +1 for the LBT_FTOP flag (inside arch.fpu) */
>>> + return sizeof(struct loongarch_lbt) / sizeof(unsigned long) + 1;
>>> +}
>>> +
>>> +static unsigned long kvm_loongarch_num_regs(struct kvm_vcpu *vcpu)
>>> +{
>>> + /* +1 for the KVM_REG_LOONGARCH_COUNTER register */
>>> + unsigned long res = CSR_MAX_NUMS + KVM_MAX_CPUCFG_REGS + 1;
>>> +
>>> + if (kvm_guest_has_lbt(&vcpu->arch))
>>> + res += kvm_loongarch_num_lbt_regs();
>>> +
>>> + return res;
>>> +}
>>> +
>>> +static int kvm_loongarch_copy_reg_indices(struct kvm_vcpu *vcpu,
>>> + u64 __user *uindices)
>>> +{
>>> + u64 reg;
>>> + unsigned int i;
>>> +
>>> + for (i = 0; i < CSR_MAX_NUMS; i++) {
>>> + reg = KVM_IOC_CSRID(i);
>>> + if (put_user(reg, uindices++))
>>> + return -EFAULT;
>>> + }
>> CSR_MAX_NUMS is max number of accessible CSR registers, instead only
>> part of them is used by vCPU model. By my understanding, there will be
>> no much meaning if CSR_MAX_NUMS is returned. And I think it will be
>> better if real CSR register id and number is returned.
>>
> Did you mean we should only return the CSR registers initialized in this
> function
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/loongarch/kvm/main.c?id=63804fed149a6750ffd28610c5c1c98cce6bd377#n48
> ?
>
> That looks like a very large list and the values of the register IDs are
> not fully continuous. If that is the case, how do we maintain the
> get/set-able CSR register list?
It will be better if CSR register list can be categorized, for example
with LoongArch CPU manual CSR register is split into 8 types from
chapter 7.4 -- 7.11
At the beginning, there is big array with size CSR_MAX_NUMS without any
category, it can be fine-gained in late.
Regards
Bibo Mao
>
>> Regards
>> Bibo Mao
>>> +
>>> + 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 <= kvm_loongarch_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 +1302,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;
>>>
>>
> Thanks,
> Zixing
>
Powered by blists - more mailing lists