From nobody Mon Feb 9 04:27:41 2026 Received: from relay1.mymailcheap.com (relay1.mymailcheap.com [144.217.248.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C37E936A000; Wed, 4 Feb 2026 11:36:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=144.217.248.100 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770204990; cv=none; b=Eg039ipezGuyMrjya9C4kLT3BD+A6V9vjmW9Zyh2mI3oB/osNzD1xnwDxS/am2HoQXCDYP1qW35VOll1BlPZ3tCPtlp4kSNRbB+NKkM57gjO+5pIVgiksggb8DB0IvRGnkO9Z44NTrAX8iJAsq4u0jZQqIFxkcYJ+DhZEVsE2Io= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770204990; c=relaxed/simple; bh=58LqpetPvvp7KfRxRprE4DTYph3Dq/zzrccU1r05rww=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=mlGNZhILmDxpCBq5ZIVVJ2/BUrcQew/F0cyZ4KEFylxbYR4ds6nA+mQK/k5pcl9+3kymRBqGHF+fw82DJQjBS4QWaxMRA/W/XbTj6LegKOFHhnKidqlixteqhbT38FJF8/au/IHfs2JSXyFlSvFNMfSInFbDZSSlvesc/1U7Ack= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=aosc.io; spf=pass smtp.mailfrom=aosc.io; dkim=pass (1024-bit key) header.d=aosc.io header.i=@aosc.io header.b=hfp6HnSa; arc=none smtp.client-ip=144.217.248.100 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=aosc.io Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=aosc.io Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=aosc.io header.i=@aosc.io header.b="hfp6HnSa" Received: from nf2.mymailcheap.com (nf2.mymailcheap.com [54.39.180.165]) by relay1.mymailcheap.com (Postfix) with ESMTPS id 4A3903E980; Wed, 4 Feb 2026 11:36:23 +0000 (UTC) Received: from mail20.mymailcheap.com (mail20.mymailcheap.com [51.83.111.147]) by nf2.mymailcheap.com (Postfix) with ESMTPSA id A9536400B6; Wed, 4 Feb 2026 11:36:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=aosc.io; s=default; t=1770204981; bh=58LqpetPvvp7KfRxRprE4DTYph3Dq/zzrccU1r05rww=; h=From:To:Cc:Subject:Date:From; b=hfp6HnSaID1je6wGMMhvx4x+k9OCuxPgggzHdQmrb+woIgr1a9d2THWhgVAoWWPaq 1nKFUme2KhJ5b3ADlpWfva1hQIoR0QGolXOZpeIyBxL9BaN6UcIQTlRIF9nVGyq1V/ YAACK+d9yJwqqGhl8cQ8oEhBgI1XyUVTbQCHe/TU= Received: from liushuyu-p15 (unknown [117.151.13.225]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail20.mymailcheap.com (Postfix) with ESMTPSA id F347641280; Wed, 4 Feb 2026 11:36:09 +0000 (UTC) From: Zixing Liu 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 , kvm@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, loongarch@lists.linux.dev, linux-riscv@lists.infradead.org Subject: [PATCH v4] KVM: Add KVM_GET_REG_LIST ioctl for LoongArch Date: Wed, 4 Feb 2026 19:36:00 +0800 Message-ID: <20260204113601.912413-1-liushuyu@aosc.io> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Rspamd-Queue-Id: A9536400B6 X-Spamd-Result: default: False [1.40 / 10.00]; MID_CONTAINS_FROM(1.00)[]; R_MISSING_CHARSET(0.50)[]; MIME_GOOD(-0.10)[text/plain]; ARC_NA(0.00)[]; ASN(0.00)[asn:16276, ipnet:51.83.0.0/16, country:FR]; RCVD_COUNT_ONE(0.00)[1]; RCPT_COUNT_TWELVE(0.00)[18]; MIME_TRACE(0.00)[0:+]; RCVD_VIA_SMTP_AUTH(0.00)[]; SPFBL_URIBL_EMAIL_FAIL(0.00)[liushuyu.aosc.io:server fail]; URIBL_BLOCKED(0.00)[mail20.mymailcheap.com:rdns,mail20.mymailcheap.com:helo]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; TO_MATCH_ENVRCPT_SOME(0.00)[]; LOCAL_OUTBOUND(0.00)[]; RCVD_TLS_ALL(0.00)[] X-Rspamd-Action: no action X-Rspamd-Server: nf2.mymailcheap.com Content-Type: text/plain; charset="utf-8" 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 --- Documentation/virt/kvm/api.rst | 2 +- arch/loongarch/kvm/vcpu.c | 87 ++++++++++++++++++++++++++++++++++ 2 files changed, 88 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. --------------------- =20 :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..bd855ee20ee2 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -3,6 +3,7 @@ * Copyright (C) 2020-2023 Loongson Technology Corporation Limited */ =20 +#include "asm/kvm_host.h" #include #include #include @@ -14,6 +15,8 @@ #define CREATE_TRACE_POINTS #include "trace.h" =20 +#define NUM_LBT_REGS 6 + const struct _kvm_stats_desc kvm_vcpu_stats_desc[] =3D { KVM_GENERIC_VCPU_STATS(), STATS_DESC_COUNTER(VCPU, int_exits), @@ -1186,6 +1189,72 @@ static int kvm_loongarch_vcpu_set_attr(struct kvm_vc= pu *vcpu, return ret; } =20 +static int kvm_loongarch_walk_csrs(struct kvm_vcpu *vcpu, u64 __user *uind= ices) +{ + unsigned int i, count; + + for (i =3D 0, count =3D 0; i < CSR_MAX_NUMS; i++) { + if (!(get_gcsr_flag(i) & (SW_GCSR | HW_GCSR))) + continue; + if (i >=3D LOONGARCH_CSR_PERFCTRL0 && i <=3D LOONGARCH_CSR_PERFCNTR3) { + /* Skip PMU CSRs if not supported by the guest */ + if (!kvm_guest_has_pmu(&vcpu->arch)) + continue; + } + const u64 reg =3D 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 =3D + kvm_loongarch_walk_csrs(vcpu, NULL) + KVM_MAX_CPUCFG_REGS + 1; + + if (kvm_guest_has_lbt(&vcpu->arch)) + res +=3D 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 =3D kvm_loongarch_walk_csrs(vcpu, uindices); + if (i < 0) + return i; + uindices +=3D i; + + for (i =3D 0; i < KVM_MAX_CPUCFG_REGS; i++) { + reg =3D KVM_IOC_CPUCFG(i); + if (put_user(reg, uindices++)) + return -EFAULT; + } + + reg =3D KVM_REG_LOONGARCH_COUNTER; + if (put_user(reg, uindices++)) + return -EFAULT; + + if (!kvm_guest_has_lbt(&vcpu->arch)) + return 0; + + for (i =3D 1; i <=3D NUM_LBT_REGS; i++) { + reg =3D (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 +1320,24 @@ long kvm_arch_vcpu_ioctl(struct file *filp, r =3D kvm_loongarch_vcpu_set_attr(vcpu, &attr); break; } + case KVM_GET_REG_LIST: { + struct kvm_reg_list __user *user_list =3D argp; + struct kvm_reg_list reg_list; + unsigned n; + + r =3D -EFAULT; + if (copy_from_user(®_list, user_list, sizeof(reg_list))) + break; + n =3D reg_list.n; + reg_list.n =3D kvm_loongarch_num_regs(vcpu); + if (copy_to_user(user_list, ®_list, sizeof(reg_list))) + break; + r =3D -E2BIG; + if (n < reg_list.n) + break; + r =3D kvm_loongarch_copy_reg_indices(vcpu, user_list->reg); + break; + } default: r =3D -ENOIOCTLCMD; break; --=20 2.53.0