From nobody Fri Sep 25 00:40:13 2026 Received: from canpmsgout11.his.huawei.com (canpmsgout11.his.huawei.com [113.46.200.226]) (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 76D653B27F7 for ; Fri, 18 Sep 2026 08:23:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.226 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789719794; cv=none; b=eMyG6bEfqjtofSI2H+jjd3EV/nbwy9Ifl1z2ujVH1YQxwjKCur5qNQJ3bKJJbV9pU+UDkCPJX2ffIrBFh0IzwMjFqdMcSKppkUnpjpA4qfqTQdUWx4lozcxqV0nNVd0BD/rEG8aSjNDdAKp88cbMEmldMaiU5gw4boGFssAcluk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789719794; c=relaxed/simple; bh=kgpSkL2haZgcDxiteaSedE60Fz3220AerE95UpX2hU0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=E/ciNE3tM6EtPtU3Oe/ztRww6qi1tovri9XxeFbTzpvpAasziWQ1HjhGfhpPQpxJLrMxj9qZZXQGsz/AvjKASWsMgHiTI+MZwZK+oR88vOQNAnFUzWXTa31hIB7OeB9IzO4KWyyloQiiknK+A6YYGKehtIw32UmwdDd0lynEPjc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=lgtSmOeP; arc=none smtp.client-ip=113.46.200.226 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="lgtSmOeP" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=FCmI3leX1pSmZveS+R3odec3VGT0tP4oB9BLzPo+eRY=; b=lgtSmOePElVqGFDjBJrpu3DHav4matcZPo1VeybjopEa14RMmu82Kgom9oIHG8JEEL5tvBfJh u8LwzRvTffwM6z3rWwSWOxrg25XVXbZV3YZILfNe2Sg6V7LHDgJUqpnlDQuyjaAl0xh0Y3YU5sA OhtH8z7IuD/QWllOzQvQ/HM= Received: from mail.maildlp.com (unknown [172.19.163.200]) by canpmsgout11.his.huawei.com (SkyGuard) with ESMTPS id 4hmQML6MVTzKm5t; Fri, 18 Sep 2026 16:11:58 +0800 (CST) Received: from dggpemr200003.china.huawei.com (unknown [7.185.36.25]) by mail.maildlp.com (Postfix) with ESMTPS id 75A8040563; Fri, 18 Sep 2026 16:23:02 +0800 (CST) Received: from huawei.com (10.50.159.234) by dggpemr200003.china.huawei.com (7.185.36.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.46; Fri, 18 Sep 2026 16:23:01 +0800 From: Yize Wang To: , , , CC: , , , , , , , , , , , , Subject: [PATCH 1/2] KVM: arm64: Add batch group constant and data structure to UAPI header Date: Fri, 18 Sep 2026 16:18:14 +0800 Message-ID: <20260918081930.4014735-2-wangyize7@huawei.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260918081930.4014735-1-wangyize7@huawei.com> References: <20260918081930.4014735-1-wangyize7@huawei.com> 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-ClientProxiedBy: kwepems200002.china.huawei.com (7.221.188.68) To dggpemr200003.china.huawei.com (7.185.36.25) Content-Type: text/plain; charset="utf-8" Add KVM_DEV_ARM_VGIC_GRP_BATCH_REGS group ID, KVM_DEV_ARM_VGIC_BATCH_MAX limit, and struct kvm_dev_arm_vgic_batch_entry for batch VGIC register access. These UAPI definitions allow userspace to read/write multiple VGIC registers in a single ioctl call. Signed-off-by: Chuan Zheng Signed-off-by: Yize Wang --- arch/arm64/include/uapi/asm/kvm.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/as= m/kvm.h index 019e5e3d892e..f84530274edd 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -418,12 +418,22 @@ enum { #define KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO 7 #define KVM_DEV_ARM_VGIC_GRP_ITS_REGS 8 #define KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ 9 +#define KVM_DEV_ARM_VGIC_GRP_BATCH_REGS 10 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT 10 #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_MASK \ (0x3fffffULL << KVM_DEV_ARM_VGIC_LINE_LEVEL_INFO_SHIFT) #define KVM_DEV_ARM_VGIC_LINE_LEVEL_INTID_MASK 0x3ff #define VGIC_LEVEL_INFO_LINE_LEVEL 0 =20 +#define KVM_DEV_ARM_VGIC_BATCH_MAX 4096 +#define KVM_DEV_ARM_VGIC_ATTR_FLAG_LOCKED 12 +struct kvm_dev_arm_vgic_batch_entry { + __u32 group; + __u64 attr; + __u32 val; + __s32 error; +}; + #define KVM_DEV_ARM_VGIC_CTRL_INIT 0 #define KVM_DEV_ARM_ITS_SAVE_TABLES 1 #define KVM_DEV_ARM_ITS_RESTORE_TABLES 2 --=20 2.43.0 From nobody Fri Sep 25 00:40:13 2026 Received: from canpmsgout03.his.huawei.com (canpmsgout03.his.huawei.com [113.46.200.218]) (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 F2946846A for ; Fri, 18 Sep 2026 08:23:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.218 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789719796; cv=none; b=lqMkDv+zo656f26hDSYO5/EiJ38wHb0XKY866EFRv2uDpKtxdfwLvRsmrQ5q1HhnCQPDoshnhr0hx3pGr1rPuMyp0x8kHJfATbrPDuUPA2dpAOSExhw4OUtt98tKKqGi5RGZQvrDSCGIRn5Iy26h5FKREsIMMIqpy8ciKVscGDI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789719796; c=relaxed/simple; bh=++Uj8D3gnWNfL3YjFHlJuXC+1Fs6HmFUENo26/NcBcs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=gRUh2BnODPdU508dxSruqdYDRsKRxpsGbYVsegLuOaGI8u2cvRqcwOMNTrdvCXMWQlpNGl3gh2b9RUPUYZI70fHzx77tkqMz+5i+T7FDk7b7nV33ftQuOKE/dE5IgyrKtvbItuircI2QpmGC5sJUScbIGMg9v4vQDtdOyzmkK3k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=LKawxbqa; arc=none smtp.client-ip=113.46.200.218 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="LKawxbqa" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=BUadRvtTRwf/90/kezmgXzTksbWqnPXbUgezkbnF2dU=; b=LKawxbqagWZtqKJ5OfXIClN6O5kePR6fYGJ74aEwh84a/T/Y6nW+MwMqraUa96Hs3rCAUYE4L e3YromFj41MQ1QR/1DzTU2NtAEqgOwwTS8A2TDqaQdQr6pqLUX4vufA3nrXV52IcZ6sg//WDD0x GvD2QUiOebSHiyWA35VoJPQ= Received: from mail.maildlp.com (unknown [172.19.163.0]) by canpmsgout03.his.huawei.com (SkyGuard) with ESMTPS id 4hmQLV3kJ8zpSy8; Fri, 18 Sep 2026 16:11:14 +0800 (CST) Received: from dggpemr200003.china.huawei.com (unknown [7.185.36.25]) by mail.maildlp.com (Postfix) with ESMTPS id 897A04057A; Fri, 18 Sep 2026 16:23:03 +0800 (CST) Received: from huawei.com (10.50.159.234) by dggpemr200003.china.huawei.com (7.185.36.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.2562.46; Fri, 18 Sep 2026 16:23:02 +0800 From: Yize Wang To: , , , CC: , , , , , , , , , , , , Subject: [PATCH 2/2] KVM: arm64: Add VGIC v3 batch register access implementation Date: Fri, 18 Sep 2026 16:18:15 +0800 Message-ID: <20260918081930.4014735-3-wangyize7@huawei.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260918081930.4014735-1-wangyize7@huawei.com> References: <20260918081930.4014735-1-wangyize7@huawei.com> 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-ClientProxiedBy: kwepems200002.china.huawei.com (7.221.188.68) To dggpemr200003.china.huawei.com (7.185.36.25) Content-Type: text/plain; charset="utf-8" Add vgic_v3_batch_access() to allow userspace to read or write multiple VGIC registers in a single system call. Introduce KVM_DEV_ARM_VGIC_ATTR_FLAG_LOCKED to modify the locking and unlocking logic in vgic_v3_attr_regs_access to prevent repeated locking and unlocking. Wire up KVM_DEV_ARM_VGIC_GRP_BATCH_REGS in vgic_v3_set_attr(), vgic_v3_get_attr(), and vgic_v3_has_attr(). Signed-off-by: Chuan Zheng Signed-off-by: Yize Wang --- arch/arm64/kvm/vgic/vgic-kvm-device.c | 113 ++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 9 deletions(-) diff --git a/arch/arm64/kvm/vgic/vgic-kvm-device.c b/arch/arm64/kvm/vgic/vg= ic-kvm-device.c index 90be99443df3..ef0b2e8f68b2 100644 --- a/arch/arm64/kvm/vgic/vgic-kvm-device.c +++ b/arch/arm64/kvm/vgic/vgic-kvm-device.c @@ -566,14 +566,21 @@ static int vgic_v3_attr_regs_access(struct kvm_device= *dev, return -EFAULT; } =20 - mutex_lock(&dev->kvm->lock); + /* If the caller has not indicated that it already holds the necessary lo= cks + * (e.g., via KVM_DEV_ARM_VGIC_ATTR_FLAG_LOCKED), we must acquire the VM = lock + * and pause all VCPUs to ensure consistent access to VGIC state. This pr= events + * race conditions with concurrent interrupt injection or VCPU execution. + */ + if (attr->flags !=3D KVM_DEV_ARM_VGIC_ATTR_FLAG_LOCKED) { + mutex_lock(&dev->kvm->lock); =20 - if (kvm_trylock_all_vcpus(dev->kvm)) { - mutex_unlock(&dev->kvm->lock); - return -EBUSY; - } + if (kvm_trylock_all_vcpus(dev->kvm)) { + mutex_unlock(&dev->kvm->lock); + return -EBUSY; + } =20 - mutex_lock(&dev->kvm->arch.config_lock); + mutex_lock(&dev->kvm->arch.config_lock); + } =20 if (!(vgic_initialized(dev->kvm) || reg_allowed_pre_init(attr))) { ret =3D -EBUSY; @@ -611,9 +618,15 @@ static int vgic_v3_attr_regs_access(struct kvm_device = *dev, } =20 out: - mutex_unlock(&dev->kvm->arch.config_lock); - kvm_unlock_all_vcpus(dev->kvm); - mutex_unlock(&dev->kvm->lock); + /* Release the locks acquired at the beginning of this function, + * but only if we actually acquired them. + * The order of unlocking must be the reverse of locking. + */ + if (attr->flags !=3D KVM_DEV_ARM_VGIC_ATTR_FLAG_LOCKED) { + mutex_unlock(&dev->kvm->arch.config_lock); + kvm_unlock_all_vcpus(dev->kvm); + mutex_unlock(&dev->kvm->lock); + } =20 if (!ret && uaccess && !is_write) { u32 __user *uaddr =3D (u32 __user *)(unsigned long)attr->addr; @@ -623,6 +636,81 @@ static int vgic_v3_attr_regs_access(struct kvm_device = *dev, return ret; } =20 +/* vgic_v3_batch_access - Batch access to VGIC registers + * + * @dev: The VGIC device + * @attr: The device attribute containing the batch entries + * @is_write: True for write, false for read + * + * This function allows userspace to read or write multiple VGIC registers + * in a single system call, reducing overhead during live migration. + * + * Returns: 0 on success, or the first error encountered. + * Individual entry errors are stored in entries[i].error. + */ +static int vgic_v3_batch_access(struct kvm_device *dev, + struct kvm_device_attr *attr, bool is_write) +{ + struct kvm_dev_arm_vgic_batch_entry __user *uentries; + struct kvm_dev_arm_vgic_batch_entry *entries; + struct kvm_device_attr sub_attr; + u32 count =3D attr->attr; + int ret =3D 0, i; + + if (!count || count > KVM_DEV_ARM_VGIC_BATCH_MAX) + return -EINVAL; + + entries =3D kvmalloc_array(count, sizeof(*entries), GFP_KERNEL); + if (!entries) + return -ENOMEM; + + uentries =3D (void __user *)attr->addr; + if (copy_from_user(entries, uentries, count * sizeof(*entries))) { + kvfree(entries); + return -EFAULT; + } + + mutex_lock(&dev->kvm->lock); + if (kvm_trylock_all_vcpus(dev->kvm)) { + mutex_unlock(&dev->kvm->lock); + kvfree(entries); + return -EBUSY; + } + mutex_lock(&dev->kvm->arch.config_lock); + + /* Process each entry in the batch */ + for (i =3D 0; i < count; i++) { + int err; + + sub_attr.group =3D entries[i].group; + sub_attr.attr =3D entries[i].attr; + sub_attr.addr =3D (unsigned long)uentries + + i * sizeof(struct kvm_dev_arm_vgic_batch_entry) + + offsetof(struct kvm_dev_arm_vgic_batch_entry, val); + + /* Set flag to indicate that locks are already held. + * This prevents vgic_v3_attr_regs_access from acquiring locks again, + * avoiding deadlock and overhead. + */ + sub_attr.flags =3D KVM_DEV_ARM_VGIC_ATTR_FLAG_LOCKED; + + err =3D vgic_v3_attr_regs_access(dev, &sub_attr, is_write); + + if (err) { + pr_err("group %d attr %lld get err %d\n", + sub_attr.group, sub_attr.attr, err); + ret =3D err; + } + } + + mutex_unlock(&dev->kvm->arch.config_lock); + kvm_unlock_all_vcpus(dev->kvm); + mutex_unlock(&dev->kvm->lock); + + kvfree(entries); + return ret; +} + static int vgic_v3_set_attr(struct kvm_device *dev, struct kvm_device_attr *attr) { @@ -649,6 +737,8 @@ static int vgic_v3_set_attr(struct kvm_device *dev, dev->kvm->arch.vgic.mi_intid =3D val; return 0; } + case KVM_DEV_ARM_VGIC_GRP_BATCH_REGS: + return vgic_v3_batch_access(dev, attr, true); default: return vgic_set_common_attr(dev, attr); } @@ -669,6 +759,8 @@ static int vgic_v3_get_attr(struct kvm_device *dev, guard(mutex)(&dev->kvm->arch.config_lock); return put_user(dev->kvm->arch.vgic.mi_intid, uaddr); } + case KVM_DEV_ARM_VGIC_GRP_BATCH_REGS: + return vgic_v3_batch_access(dev, attr, false); default: return vgic_get_common_attr(dev, attr); } @@ -707,6 +799,9 @@ static int vgic_v3_has_attr(struct kvm_device *dev, case KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES: return 0; } + break; + case KVM_DEV_ARM_VGIC_GRP_BATCH_REGS: + return 0; } return -ENXIO; } --=20 2.43.0