[PATCH v2 RESEND] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch

Zixing Liu posted 1 patch 1 week, 1 day ago
There is a newer version of this series
Documentation/virt/kvm/api.rst |  2 +-
arch/loongarch/kvm/vcpu.c      | 85 ++++++++++++++++++++++++++++++++++
2 files changed, 86 insertions(+), 1 deletion(-)
[PATCH v2 RESEND] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch
Posted by Zixing Liu 1 week, 1 day ago
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@aosc.io>
---
 Documentation/virt/kvm/api.rst |  2 +-
 arch/loongarch/kvm/vcpu.c      | 85 ++++++++++++++++++++++++++++++++++
 2 files changed, 86 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..ed11438f4544 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -1186,6 +1186,73 @@ 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)))
+			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_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 =
+		kvm_loongarch_walk_csrs(vcpu, NULL) + 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;
+
+	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 <= 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 +1318,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(&reg_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, &reg_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
Re: [PATCH v2 RESEND] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch
Posted by Huacai Chen 1 week, 1 day ago
Hi, Zixing,

On Sat, Jan 31, 2026 at 2:07 PM Zixing Liu <liushuyu@aosc.io> 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@aosc.io>
> ---
>  Documentation/virt/kvm/api.rst |  2 +-
>  arch/loongarch/kvm/vcpu.c      | 85 ++++++++++++++++++++++++++++++++++
>  2 files changed, 86 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..ed11438f4544 100644
> --- a/arch/loongarch/kvm/vcpu.c
> +++ b/arch/loongarch/kvm/vcpu.c
> @@ -1186,6 +1186,73 @@ 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)))
> +                       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_lbt_regs(void)
> +{
> +       /* +1 for the LBT_FTOP flag (inside arch.fpu) */
> +       return sizeof(struct loongarch_lbt) / sizeof(unsigned long) + 1;
> +}
This function has only one line, I think it is better to embed it into
the caller.

Huacai

> +
> +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 += 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;
> +
> +       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 <= 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 +1318,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(&reg_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, &reg_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
>
Re: [PATCH v2 RESEND] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch
Posted by liushuyu 1 week, 1 day ago
Hi Huacai,

> Hi, Zixing,
>
> On Sat, Jan 31, 2026 at 2:07 PM Zixing Liu <liushuyu@aosc.io> 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@aosc.io>
>> ---
>>  Documentation/virt/kvm/api.rst |  2 +-
>>  arch/loongarch/kvm/vcpu.c      | 85 ++++++++++++++++++++++++++++++++++
>>  2 files changed, 86 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..ed11438f4544 100644
>> --- a/arch/loongarch/kvm/vcpu.c
>> +++ b/arch/loongarch/kvm/vcpu.c
>> @@ -1186,6 +1186,73 @@ 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)))
>> +                       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_lbt_regs(void)
>> +{
>> +       /* +1 for the LBT_FTOP flag (inside arch.fpu) */
>> +       return sizeof(struct loongarch_lbt) / sizeof(unsigned long) + 1;
>> +}
> This function has only one line, I think it is better to embed it into
> the caller.

This function was used twice in this patch. If the hardware gained more
LBT registers that are not recorded in `struct loongarch_lbt` in the
future, I am afraid changing manually inlined logic will be a bit
error-prone.

Maybe one compromise would be making this a `const` variable somewhere
in this file instead of a function? What do you think?

> Huacai

Thanks,

Zixing

>> +
>> +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 += 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;
>> +
>> +       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 <= 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 +1318,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(&reg_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, &reg_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
>>
Re: [PATCH v2 RESEND] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch
Posted by Huacai Chen 1 week ago
On Sat, Jan 31, 2026 at 10:09 PM liushuyu <liushuyu@aosc.io> wrote:
>
> Hi Huacai,
>
> > Hi, Zixing,
> >
> > On Sat, Jan 31, 2026 at 2:07 PM Zixing Liu <liushuyu@aosc.io> 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@aosc.io>
> >> ---
> >>  Documentation/virt/kvm/api.rst |  2 +-
> >>  arch/loongarch/kvm/vcpu.c      | 85 ++++++++++++++++++++++++++++++++++
> >>  2 files changed, 86 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..ed11438f4544 100644
> >> --- a/arch/loongarch/kvm/vcpu.c
> >> +++ b/arch/loongarch/kvm/vcpu.c
> >> @@ -1186,6 +1186,73 @@ 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)))
> >> +                       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_lbt_regs(void)
> >> +{
> >> +       /* +1 for the LBT_FTOP flag (inside arch.fpu) */
> >> +       return sizeof(struct loongarch_lbt) / sizeof(unsigned long) + 1;
> >> +}
> > This function has only one line, I think it is better to embed it into
> > the caller.
>
> This function was used twice in this patch. If the hardware gained more
> LBT registers that are not recorded in `struct loongarch_lbt` in the
> future, I am afraid changing manually inlined logic will be a bit
> error-prone.
If this really happens, how to keep compatibility?

>
> Maybe one compromise would be making this a `const` variable somewhere
> in this file instead of a function? What do you think?

I think the best way is
#define NUM_LBT_REGS 6
in this file.

Huacai

>
> > Huacai
>
> Thanks,
>
> Zixing
>
> >> +
> >> +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 += 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;
> >> +
> >> +       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 <= 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 +1318,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(&reg_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, &reg_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
> >>
>