* [PATCH 1/1] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch @ 2026-01-25 5:43 Zixing Liu 2026-01-26 2:09 ` Bibo Mao 0 siblings, 1 reply; 9+ messages in thread From: Zixing Liu @ 2026-01-25 5:43 UTC (permalink / raw) To: WANG Xuerui, Huacai Chen, Bibo Mao Cc: Kexy Biscuit, Mingcong Bai, Zixing Liu, Paolo Bonzini, Jonathan Corbet, Tianrui Zhao, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, kvm, linux-doc, linux-kernel, loongarch, linux-riscv, rust-for-linux 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@aosc.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; + } + + 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; -- 2.52.0 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/1] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch 2026-01-25 5:43 [PATCH 1/1] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch Zixing Liu @ 2026-01-26 2:09 ` Bibo Mao 2026-01-26 3:38 ` liushuyu 0 siblings, 1 reply; 9+ messages in thread From: Bibo Mao @ 2026-01-26 2:09 UTC (permalink / raw) To: Zixing Liu, WANG Xuerui, Huacai Chen Cc: Kexy Biscuit, Mingcong Bai, Paolo Bonzini, Jonathan Corbet, Tianrui Zhao, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, kvm, linux-doc, linux-kernel, loongarch, linux-riscv, rust-for-linux 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@aosc.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. 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; > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/1] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch 2026-01-26 2:09 ` Bibo Mao @ 2026-01-26 3:38 ` liushuyu 2026-01-26 3:57 ` Bibo Mao 0 siblings, 1 reply; 9+ messages in thread From: liushuyu @ 2026-01-26 3:38 UTC (permalink / raw) To: Bibo Mao, WANG Xuerui, Huacai Chen Cc: Kexy Biscuit, Mingcong Bai, Paolo Bonzini, Jonathan Corbet, Tianrui Zhao, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, kvm, linux-doc, linux-kernel, loongarch, linux-riscv, rust-for-linux 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@aosc.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? > 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 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/1] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch 2026-01-26 3:38 ` liushuyu @ 2026-01-26 3:57 ` Bibo Mao 2026-01-26 4:22 ` liushuyu 0 siblings, 1 reply; 9+ messages in thread From: Bibo Mao @ 2026-01-26 3:57 UTC (permalink / raw) To: liushuyu, WANG Xuerui, Huacai Chen Cc: Kexy Biscuit, Mingcong Bai, Paolo Bonzini, Jonathan Corbet, Tianrui Zhao, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, kvm, linux-doc, linux-kernel, loongarch, linux-riscv, rust-for-linux 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@aosc.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 > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/1] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch 2026-01-26 3:57 ` Bibo Mao @ 2026-01-26 4:22 ` liushuyu 2026-01-26 8:36 ` Bibo Mao 0 siblings, 1 reply; 9+ messages in thread From: liushuyu @ 2026-01-26 4:22 UTC (permalink / raw) To: Bibo Mao, WANG Xuerui, Huacai Chen Cc: Kexy Biscuit, Mingcong Bai, Paolo Bonzini, Jonathan Corbet, Tianrui Zhao, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, kvm, linux-doc, linux-kernel, loongarch, linux-riscv, rust-for-linux Hi Bibo, > > > 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@aosc.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. Does that mean in the new `kvm_loongarch_copy_reg_indices` function, it is also okay to embed this big list in there? Or do you want to extract the list from the `kvm_init_gcsr_flag` function and refactor both functions to share one single big list (probably in the kvm_host.h header)? Because from what I could understand, your previous messages point to that we need to use this list to make out what CSR registers to return to the user space VMMs. > > 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 >> > Thanks, Zixing ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/1] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch 2026-01-26 4:22 ` liushuyu @ 2026-01-26 8:36 ` Bibo Mao 2026-01-26 8:54 ` liushuyu 0 siblings, 1 reply; 9+ messages in thread From: Bibo Mao @ 2026-01-26 8:36 UTC (permalink / raw) To: liushuyu, WANG Xuerui, Huacai Chen Cc: Kexy Biscuit, Mingcong Bai, Paolo Bonzini, Jonathan Corbet, Tianrui Zhao, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, kvm, linux-doc, linux-kernel, loongarch, linux-riscv, rust-for-linux On 2026/1/26 下午12:22, liushuyu wrote: > Hi Bibo, > >> >> >> 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@aosc.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. > > Does that mean in the new `kvm_loongarch_copy_reg_indices` function, it > is also okay to embed this big list in there? Firstly I do not know how to use ioctl command KVM_GET_REG_LIST in VMM actually. At the second from the word "determine which (special) registers are get/set-able", I think that it is better to set accessible CSR register number and ID rather than the total number CSR_MAX_NUMS. +static int kvm_loongarch_num_csr_regs(struct kvm_vcpu *vcpu) +{ + unsigned int i, count; + + count = 0 + for (i = 0; i < CSR_MAX_NUMS; i++) { + if (!(get_gcsr_flag(i) & (SW_GCSR | HW_GCSR))) + continue; + 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_num_csr_regs + 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++) { + if (!(get_gcsr_flag(i) & (SW_GCSR | HW_GCSR))) + continue; reg = KVM_IOC_CSRID(i); if (put_user(reg, uindices++)) return -EFAULT; } Regards Bibo Mao > > Or do you want to extract the list from the `kvm_init_gcsr_flag` > function and refactor both functions to share one single big list > (probably in the kvm_host.h header)? > > Because from what I could understand, your previous messages point to > that we need to use this list to make out what CSR registers to return > to the user space VMMs. > >> >> 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 >>> >> > Thanks, > Zixing > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/1] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch 2026-01-26 8:36 ` Bibo Mao @ 2026-01-26 8:54 ` liushuyu 2026-01-26 9:35 ` Bibo Mao 0 siblings, 1 reply; 9+ messages in thread From: liushuyu @ 2026-01-26 8:54 UTC (permalink / raw) To: Bibo Mao, WANG Xuerui, Huacai Chen Cc: Kexy Biscuit, Mingcong Bai, Paolo Bonzini, Jonathan Corbet, Tianrui Zhao, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, kvm, linux-doc, linux-kernel, loongarch, linux-riscv, rust-for-linux Hi Bibo, > > > On 2026/1/26 下午12:22, liushuyu wrote: >> Hi Bibo, >> >>> >>> >>> 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@aosc.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. >> >> Does that mean in the new `kvm_loongarch_copy_reg_indices` function, it >> is also okay to embed this big list in there? > Firstly I do not know how to use ioctl command KVM_GET_REG_LIST in VMM > actually. > > At the second from the word "determine which (special) registers are > get/set-able", I think that it is better to set accessible CSR > register number and ID rather than the total number CSR_MAX_NUMS. > Understood. I will post a v2 patch, and we can continue the discussion from there to see if I understood your points correctly. > +static int kvm_loongarch_num_csr_regs(struct kvm_vcpu *vcpu) > +{ > + unsigned int i, count; > + > + count = 0 > + for (i = 0; i < CSR_MAX_NUMS; i++) { > + if (!(get_gcsr_flag(i) & (SW_GCSR | HW_GCSR))) > + continue; > + 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_num_csr_regs + > 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++) { > + if (!(get_gcsr_flag(i) & (SW_GCSR | HW_GCSR))) > + continue; > reg = KVM_IOC_CSRID(i); > if (put_user(reg, uindices++)) > return -EFAULT; > } > > Regards > Bibo Mao >> >> Or do you want to extract the list from the `kvm_init_gcsr_flag` >> function and refactor both functions to share one single big list >> (probably in the kvm_host.h header)? >> >> Because from what I could understand, your previous messages point to >> that we need to use this list to make out what CSR registers to return >> to the user space VMMs. > >> >>> >>> 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 >>>> >>> >> Thanks, >> Zixing >> > Thanks, Zixing ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/1] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch 2026-01-26 8:54 ` liushuyu @ 2026-01-26 9:35 ` Bibo Mao 2026-01-26 10:03 ` liushuyu 0 siblings, 1 reply; 9+ messages in thread From: Bibo Mao @ 2026-01-26 9:35 UTC (permalink / raw) To: liushuyu, WANG Xuerui, Huacai Chen Cc: Kexy Biscuit, Mingcong Bai, Paolo Bonzini, Jonathan Corbet, Tianrui Zhao, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, kvm, linux-doc, linux-kernel, loongarch, linux-riscv, rust-for-linux On 2026/1/26 下午4:54, liushuyu wrote: > Hi Bibo, > >> >> >> On 2026/1/26 下午12:22, liushuyu wrote: >>> Hi Bibo, >>> >>>> >>>> >>>> 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@aosc.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. >>> >>> Does that mean in the new `kvm_loongarch_copy_reg_indices` function, it >>> is also okay to embed this big list in there? >> Firstly I do not know how to use ioctl command KVM_GET_REG_LIST in VMM >> actually. >> >> At the second from the word "determine which (special) registers are >> get/set-able", I think that it is better to set accessible CSR >> register number and ID rather than the total number CSR_MAX_NUMS. >> > Understood. I will post a v2 patch, and we can continue the discussion > from there to see if I understood your points correctly. Remember to add such lines in function kvm_init_gcsr_flag() in the next round, since MSGINT CSR registers are missing here. void kvm_init_gcsr_flag(void) { + if (cpu_has_msgint) { + set_gcsr_hw_flag(LOONGARCH_CSR_ISR0); + set_gcsr_hw_flag(LOONGARCH_CSR_ISR1); + set_gcsr_hw_flag(LOONGARCH_CSR_ISR2); + set_gcsr_hw_flag(LOONGARCH_CSR_ISR3); + } } Regards Bibo Mao > >> +static int kvm_loongarch_num_csr_regs(struct kvm_vcpu *vcpu) >> +{ >> + unsigned int i, count; >> + >> + count = 0 >> + for (i = 0; i < CSR_MAX_NUMS; i++) { >> + if (!(get_gcsr_flag(i) & (SW_GCSR | HW_GCSR))) >> + continue; >> + 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_num_csr_regs + >> 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++) { >> + if (!(get_gcsr_flag(i) & (SW_GCSR | HW_GCSR))) >> + continue; >> reg = KVM_IOC_CSRID(i); >> if (put_user(reg, uindices++)) >> return -EFAULT; >> } >> >> Regards >> Bibo Mao >>> >>> Or do you want to extract the list from the `kvm_init_gcsr_flag` >>> function and refactor both functions to share one single big list >>> (probably in the kvm_host.h header)? >>> >>> Because from what I could understand, your previous messages point to >>> that we need to use this list to make out what CSR registers to return >>> to the user space VMMs. >> >>> >>>> >>>> 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 >>>>> >>>> >>> Thanks, >>> Zixing >>> >> > Thanks, > > Zixing > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 1/1] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch 2026-01-26 9:35 ` Bibo Mao @ 2026-01-26 10:03 ` liushuyu 0 siblings, 0 replies; 9+ messages in thread From: liushuyu @ 2026-01-26 10:03 UTC (permalink / raw) To: Bibo Mao, WANG Xuerui, Huacai Chen Cc: Kexy Biscuit, Mingcong Bai, Paolo Bonzini, Jonathan Corbet, Tianrui Zhao, Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, Danilo Krummrich, kvm, linux-doc, linux-kernel, loongarch, linux-riscv, rust-for-linux Hi Bibo, > > > On 2026/1/26 下午4:54, liushuyu wrote: >> Hi Bibo, >> >>> >>> >>> On 2026/1/26 下午12:22, liushuyu wrote: >>>> Hi Bibo, >>>> >>>>> >>>>> >>>>> 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@aosc.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. >>>> >>>> Does that mean in the new `kvm_loongarch_copy_reg_indices` >>>> function, it >>>> is also okay to embed this big list in there? >>> Firstly I do not know how to use ioctl command KVM_GET_REG_LIST in VMM >>> actually. >>> >>> At the second from the word "determine which (special) registers are >>> get/set-able", I think that it is better to set accessible CSR >>> register number and ID rather than the total number CSR_MAX_NUMS. >>> >> Understood. I will post a v2 patch, and we can continue the discussion >> from there to see if I understood your points correctly. > Remember to add such lines in function kvm_init_gcsr_flag() in the > next round, since MSGINT CSR registers are missing here. > > void kvm_init_gcsr_flag(void) { > + if (cpu_has_msgint) { > + set_gcsr_hw_flag(LOONGARCH_CSR_ISR0); > + set_gcsr_hw_flag(LOONGARCH_CSR_ISR1); > + set_gcsr_hw_flag(LOONGARCH_CSR_ISR2); > + set_gcsr_hw_flag(LOONGARCH_CSR_ISR3); > + } > } > I think this might need to be a separate patch or commit. Do you want me to include this in the KVM_GET_REG_LIST patch, or do you want to submit this change separately? > Regards > Bibo Mao >> >>> +static int kvm_loongarch_num_csr_regs(struct kvm_vcpu *vcpu) >>> +{ >>> + unsigned int i, count; >>> + >>> + count = 0 >>> + for (i = 0; i < CSR_MAX_NUMS; i++) { >>> + if (!(get_gcsr_flag(i) & (SW_GCSR | HW_GCSR))) >>> + continue; >>> + 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_num_csr_regs + >>> 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++) { >>> + if (!(get_gcsr_flag(i) & (SW_GCSR | HW_GCSR))) >>> + continue; >>> reg = KVM_IOC_CSRID(i); >>> if (put_user(reg, uindices++)) >>> return -EFAULT; >>> } >>> >>> Regards >>> Bibo Mao >>>> >>>> Or do you want to extract the list from the `kvm_init_gcsr_flag` >>>> function and refactor both functions to share one single big list >>>> (probably in the kvm_host.h header)? >>>> >>>> Because from what I could understand, your previous messages point to >>>> that we need to use this list to make out what CSR registers to return >>>> to the user space VMMs. >>> >>>> >>>>> >>>>> 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 >>>>>> >>>>> >>>> Thanks, >>>> Zixing >>>> >>> >> Thanks, >> >> Zixing >> > Thanks, Zixing ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-01-26 10:03 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-01-25 5:43 [PATCH 1/1] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch Zixing Liu 2026-01-26 2:09 ` Bibo Mao 2026-01-26 3:38 ` liushuyu 2026-01-26 3:57 ` Bibo Mao 2026-01-26 4:22 ` liushuyu 2026-01-26 8:36 ` Bibo Mao 2026-01-26 8:54 ` liushuyu 2026-01-26 9:35 ` Bibo Mao 2026-01-26 10:03 ` liushuyu
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®