From nobody Sat Jun 13 23:46:20 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (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 46BD526F29C for ; Sat, 13 Jun 2026 17:43:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781372635; cv=none; b=O6NgDj8Qna2u8te6eBzkusop8GZAmOocV5ktFWXlcJjpt3SlTgLMuGW8479IqFtrgLUOEcU/SPLnmMdJRIcTHMqIMrYWdGZwLDCGIBpWRofcfQwZXyjWZkX5OTYBsp5ekt+28zlUqp+26bRJHEB13o8dSfRrF5nAmLP2F7eDL04= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781372635; c=relaxed/simple; bh=i1C+7GVwz8hqSxonETSP8Z7foT49r9/TUeD3+VkK9Uo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=BHXpJWfG1pGhiE+TtLSlkJMoFcIbFJF8JimKZAKNItsObioO99DUsIyPXkGrpF1vVgoTGbQC/IYi4ARha6tDyJPB+mvnM5TBLTNcEIJIcdAU8gJqXbdlo8lQkxHK9RM7tvqP5NDORt2DynFN/XHT8dpLHw1dtaTnuhuS6HQzK/o= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=kImBcS6E; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=IicaYopM; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="kImBcS6E"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="IicaYopM" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 65DFAph53283442 for ; Sat, 13 Jun 2026 17:43:53 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= eliVjm18cWWxfayAi3KcJNFoMA1vSR2kzp1VWaYb3AQ=; b=kImBcS6EHxWaZhVb eWG8NPJ65KU3oR5iGbYrvJcA6jHUdsfeZgkAJDcABqT+SOK3ezsJxlL+/cChSysy TCE0700ld5UrGtJy6KUHekJbF5H1P+FzsQwzgPnYkwgOv1azfubaaUEgseT3wd/v rVB9wsjjcz80KJ0sqy9YjxRu/u9V3d3l/TlRtHgrH4zBFY9ujLcmGRJ/ER5nqd87 J54Gfo8vVvqut8gWligtjGCn9QU5+X7HOZ2cT4ARviBXyNTfX03SEM7DDsszrI98 wgBdG69yliJ0yuDcMr9r+NMhS5NS09DQrGtJRXLD8gHpHxE6tkKrfnVrCLyVJPAJ Qy2e/g== Received: from mail-pg1-f197.google.com (mail-pg1-f197.google.com [209.85.215.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4ery8wsnt8-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Sat, 13 Jun 2026 17:43:53 +0000 (GMT) Received: by mail-pg1-f197.google.com with SMTP id 41be03b00d2f7-c856470fe9fso950496a12.2 for ; Sat, 13 Jun 2026 10:43:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1781372632; x=1781977432; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=eliVjm18cWWxfayAi3KcJNFoMA1vSR2kzp1VWaYb3AQ=; b=IicaYopM9yt+UCtWQBp2nw/ra5uGB4NVyrNl7s1hAetUP+NxZK1RIg42NxxW8csB0L 1dgXwIfk7tyEuQyV5PbZYYgFVjfjemrBtJenhFwrXYRyUuKtZJRUa4ZVugspJaLNEnGX k/AtfU3XDII/QGlxhoHK49hJjWO+wjJQMdy3IADilgVTK4oLU+IlkwFxt0oTa1BoGr84 hHiTvWEY+6tf1Dc1eeXZq0qH3GBtWuHfifYUDLhtF4F/1cejLOwIlHqOqtZi5mUyJsHV E2GvloeFFHGyYVZF9Ay+ID8ETum/ybiQ0ILnUFXeRHzkdKn1ATkAbPncaDHWHAr1nD2w cuoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781372632; x=1781977432; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=eliVjm18cWWxfayAi3KcJNFoMA1vSR2kzp1VWaYb3AQ=; b=BU+q+meg1GoB0uzdLKeiSc67yGlN7X9lYF1QnG7GkoKaru3ulliS/vbBbtzDmKkwur dP8Rk9dAm7IOcZu9sP0AVZRrae7uczkTy/y1+A/0GvqGlEgZmwudD3yRbexzarAPZv8E vLRzwlhWTJigLjcxoaRkTDHBHQhGIHLyhI/zTcYiX5oQxNAwpisRoD6WMTAwcRq2yW6x D6AgZWX2OUIXUvi1gZa/AWWOrxQogkEXsJpr1ZBxtWNRDBtMSsoaQVct7xDeZYLAeoz9 F//JPeoy9g5iqYGfCS6G/MzKEM7CskVWeZDcVPUhKZmd93ENS+tiAs6xQoEbZmgfTTla Czdg== X-Forwarded-Encrypted: i=1; AFNElJ/fqBB8xPLIw+addQkQ+DsmfDcKDrxq5+FGFekdR+jxHoHWUaAnd09TssvSdlu8qZjhZeft01gAJDD2e+k=@vger.kernel.org X-Gm-Message-State: AOJu0YxQ3ty9JEARXw7yUT/MTwoQtPQeDUCg2PuCwJPWBKsmFLVrQTVW 65PLKosuaG2HOIoJuWjD3/gDed9sjBOfu49aa5JamrhQAEAN8NHv2rIcwsX+zJiFkspU7IbbSdA LJ51dcQGwZp2FnMMmA93aaeVkHAvCkLQR8k4Nn304aaSMfELzt+j7PnaoUiiLMnVu/AQ= X-Gm-Gg: Acq92OHqAQQWsE+jv64v+yjSwjlfmTCNpLYF75Rca7RCrO7CBB5wEbSSgqNswhA5Jyr zQt11JfgsBtbVqqA5ukEAYLv2sxq5r72E2fIuAMaw78UAC4U6PH/SLH8mY1UUd7atWn5uk+Q0Xd 8iwj90hcBPjCtmIFUSEKvp545l2oNPyoJTUju9jjeSK75dIoMGx/Dlqj6vTmhwF4AuUbqZWzYiv 2TVFoVDi32MY2s77MShOF18NA5quB5QPKqXPAuKCLBow5xf7qqMm5t/MWiKfT650n0MfxmJDEm2 t8/RkKtpx8bhKMh2YHCmIcgMETw6Ldl3JaCFCySZdZ3Wbm3J+2A6RRg64vNqoE7dJVNeURkqyXA QzQUOoPyWTJ5otQDH4QiHxhdEWflEYanT4UYfrQWaF4WvlQonpni4VA== X-Received: by 2002:a05:6a00:1f0f:b0:822:6830:5900 with SMTP id d2e1a72fcca58-8434cdcaeedmr7853512b3a.6.1781372631976; Sat, 13 Jun 2026 10:43:51 -0700 (PDT) X-Received: by 2002:a05:6a00:1f0f:b0:822:6830:5900 with SMTP id d2e1a72fcca58-8434cdcaeedmr7853490b3a.6.1781372631441; Sat, 13 Jun 2026 10:43:51 -0700 (PDT) Received: from hu-pranarya-hyd.qualcomm.com ([202.46.22.19]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8434b055095sm6594096b3a.57.2026.06.13.10.43.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 13 Jun 2026 10:43:51 -0700 (PDT) From: Pranjal Arya Date: Sat, 13 Jun 2026 23:13:36 +0530 Subject: [PATCH RFC 1/3] vfio/pci: Virtualize and scrub Device Serial Number from guests Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260613-pcie_vfio-v1-1-09168188f3f2@oss.qualcomm.com> References: <20260613-pcie_vfio-v1-0-09168188f3f2@oss.qualcomm.com> In-Reply-To: <20260613-pcie_vfio-v1-0-09168188f3f2@oss.qualcomm.com> To: Alex Williamson , Bjorn Helgaas , David Matlack , Shuah Khan Cc: linux-arm-msm@vger.kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, linux-kselftest@vger.kernel.org, Pranjal Shrivastava , Manivannan Sadhasivam , Pranjal Arya X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1781372623; l=6577; i=pranjal.arya@oss.qualcomm.com; s=20260516; h=from:subject:message-id; bh=i1C+7GVwz8hqSxonETSP8Z7foT49r9/TUeD3+VkK9Uo=; b=0WN5zT+Mq0FFfXU8VJ/YH6TO/KCuwKs/cW5LjPcv4yOeQbyQZTmTdoNW8qaJbx1tTpv/Q3RgX ZLlGyyE6HAuA62vYVsgUD0/O6tvmiALyVOt6/LY2rnDJb1+elDq4NvX X-Developer-Key: i=pranjal.arya@oss.qualcomm.com; a=ed25519; pk=ymtcTlccEIDsi3ErhpjIoZZHKdPBYWGWW0Lchs5MsbE= X-Proofpoint-ORIG-GUID: -QfSzYN87HS7w4Xu0-iJasVTN-TE-7e9 X-Proofpoint-GUID: -QfSzYN87HS7w4Xu0-iJasVTN-TE-7e9 X-Proofpoint-Spam-Info: AW1haW4tMjYwNjEzMDE4NSBTYWx0ZWRfXxnKy2ONWPQE/ yF1iqI3Y+38EKcVPTv7TjS0Bx0XkLjvJAH40lCvclvMtqHsDsg2FIdrD4aPGMr3RBaH1cCUr3bj W3DRpRV98BoeFDJllwegYiDnErLHPMo= X-Authority-Analysis: v=2.4 cv=IqAutr/g c=1 sm=1 tr=0 ts=6a2d96d9 cx=c_pps a=rz3CxIlbcmazkYymdCej/Q==:117 a=fChuTYTh2wq5r3m49p7fHw==:17 a=IkcTkHD0fZMA:10 a=FelO9ux0wxsA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=EUspDBNiAAAA:8 a=Sm3NOD-Glf8aR10cVYQA:9 a=QEXdDO2ut3YA:10 a=bFCP_H2QrGi7Okbo017w:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjEzMDE4NSBTYWx0ZWRfXxDGLVRoLdxN8 sZdvEpMVfhqVnIlWmj8BvfRbQ+GDQ/eUlIMSYru/tRnTWBldDc6PEqKgpwKMx3p04PUxHuQmnpP iS+Om2uxRDPRxyjPjdFx2CR9/uezM5zAVRJ/nEYZNohXX5piuEdN6KjskMAmmKs+O5Z5/99n/xD FfRqna48Cha2NBs/cTdXgQr2ATJ4IakVAoKhPKTKGSgo12yfpHd/uFBI75vcVWTmd4LxEvZ1RDR eUxF2ROR4NraFAzoufGBosv9TZeYPjUo8rE9v40mKFKftMYmrAEP5BYfW5mLDsGdp+nTUopUyQ4 QiIdCsEp6XA4bvrTkONyMNwBlF8ru2xe7G1MT1qJWKsVRN9B/vqrdpb/cJRVTZytdGnGfVUFJLp mvQX9mKajNeQ+7L7UO5oy40Kov6R9HwnoBwzkRujDxOSBvsckqNR5di/rQ+g9l/yyQguikOtidy bJcCoEGo2jOu8skyX2g== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-13_03,2026-06-12_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 suspectscore=0 priorityscore=1501 malwarescore=0 phishscore=0 adultscore=0 lowpriorityscore=0 spamscore=0 bulkscore=0 clxscore=1015 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606040000 definitions=main-2606130185 The PCIe Device Serial Number (DSN) Extended Capability reports a unique, persistent hardware serial number (PCIe r6.2 sec 7.9.3). The value identifies the physical component: per the spec the functions of a Multi-Function Device that implement the capability report the same DSN, so a single value can fingerprint a whole physical device. Root Complex integrated Endpoints (RCiEPs) may implement the capability independently and are not required to share their value with other RCiEPs of the same Root Complex, but each such value is still a stable, host-specific identifier. vfio-pci has no perm_bits entry for the DSN capability, so guest reads of the serial number fall through to the physical device. This leaks a stable hardware identifier into the guest that can be used to fingerprint the host device and correlate it across VMs, which is undesirable for multi-tenant passthrough. Add a perm_bits initializer that fully virtualizes the DSN capability: the header dword and both serial-number dwords (PCI_DSN_CAP, PCI_DSN_LOW_DW, PCI_DSN_HIGH_DW) are marked ALL_VIRT/NO_WRITE so all reads are served from the virtualized config space rather than hardware and writes are denied (the DSN is read-only state). Scrub the serial in vconfig during vfio_ecap_init() so guests read a zeroed serial while the capability remains visible. Add the DSN register-offset defines to pci_regs.h. The capability length used by alloc_perm_bits() comes from the existing pci_ext_cap_length[PCI_EXT_CAP_ID_DSN] =3D PCI_EXT_CAP_DSN_SIZEOF (12), which covers the 4-byte header plus the 8-byte serial. SR-IOV: per the SR-IOV spec a PF's DSN applies to all of its VFs, and a VF that implements the DSN capability must report the same value as its PF. vfio-pci exposes only the assigned device's own config space to the guest, and neither the vconfig fill nor the vfio_ecap_init() walk applies any VF-specific transform to the DSN bytes, so the DSN capability is virtualized and scrubbed for a VF exactly as for a PF. Therefore a VF that implements DSN (whose value is the PF's host serial) is scrubbed, and a VF that omits the capability (the spec-recommended case) exposes no serial to scrub. Variant drivers (mlx5-vfio-pci, hisi-acc-vfio-pci, nvgrace-gpu-vfio-pci, virtio-vfio-pci, etc.) build on vfio-pci-core and share this config-space path and perm_bits table, so the scrub applies to them as well. The scrub is the default because a guest cannot rely on a meaningful DSN through vfio-pci in general (it identifies the physical device, which varies across assignment and migration). The following patch lets the VMM present a chosen serial where a stable identity is required. Signed-off-by: Pranjal Arya --- drivers/vfio/pci/vfio_pci_config.c | 39 ++++++++++++++++++++++++++++++++++= ++++ include/uapi/linux/pci_regs.h | 5 +++++ 2 files changed, 44 insertions(+) diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci= _config.c index a10ed733f0e3..24dfeb43cb71 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -1085,6 +1085,31 @@ static int __init init_pci_ext_cap_pwr_perm(struct p= erm_bits *perm) return 0; } =20 +/* + * The Device Serial Number is a unique, persistent, per-device identifier. + * Passing the physical serial number through to a guest leaks an identifi= er + * that can be used to fingerprint and correlate the host device across VMs + * and tenants. Virtualize the whole capability so reads come from vconfig + * (which is scrubbed during init, see vfio_ecap_init()) instead of hardwa= re, + * and disallow writes (the DSN is read-only hardware state anyway). + */ +static int __init init_pci_ext_cap_dsn_perm(struct perm_bits *perm) +{ + if (alloc_perm_bits(perm, pci_ext_cap_length[PCI_EXT_CAP_ID_DSN])) + return -ENOMEM; + + /* + * Virtualize the whole capability: the header (offset 0) plus the + * two serial-number dwords (offsets 4 and 8). All reads are then + * served from vconfig (scrubbed in vfio_ecap_init()) rather than + * hardware, and writes are denied since the DSN is read-only state. + */ + p_setd(perm, 0, ALL_VIRT, NO_WRITE); + p_setd(perm, 4, ALL_VIRT, NO_WRITE); + p_setd(perm, 8, ALL_VIRT, NO_WRITE); + return 0; +} + /* * Initialize the shared permission tables */ @@ -1100,6 +1125,7 @@ void vfio_pci_uninit_perm_bits(void) =20 free_perm_bits(&ecap_perms[PCI_EXT_CAP_ID_ERR]); free_perm_bits(&ecap_perms[PCI_EXT_CAP_ID_PWR]); + free_perm_bits(&ecap_perms[PCI_EXT_CAP_ID_DSN]); } =20 int __init vfio_pci_init_perm_bits(void) @@ -1120,6 +1146,7 @@ int __init vfio_pci_init_perm_bits(void) /* Extended capabilities */ ret |=3D init_pci_ext_cap_err_perm(&ecap_perms[PCI_EXT_CAP_ID_ERR]); ret |=3D init_pci_ext_cap_pwr_perm(&ecap_perms[PCI_EXT_CAP_ID_PWR]); + ret |=3D init_pci_ext_cap_dsn_perm(&ecap_perms[PCI_EXT_CAP_ID_DSN]); ecap_perms[PCI_EXT_CAP_ID_VNDR].writefn =3D vfio_raw_config_write; ecap_perms[PCI_EXT_CAP_ID_DVSEC].writefn =3D vfio_raw_config_write; =20 @@ -1702,6 +1729,18 @@ static int vfio_ecap_init(struct vfio_pci_core_devic= e *vdev) if (ret) return ret; =20 + /* + * Scrub the physical Device Serial Number from the + * virtualized config space so the guest cannot read the + * host device's unique identifier. The capability is fully + * virtualized (see init_pci_ext_cap_dsn_perm()), so reads + * return this scrubbed value rather than hardware. The user + * can present a chosen serial via VFIO_DEVICE_FEATURE_PCI_DSN. + */ + if (ecap =3D=3D PCI_EXT_CAP_ID_DSN) + memset(&vdev->vconfig[epos + PCI_DSN_LOW_DW], 0, + sizeof(__le64)); + /* * If we're just using this capability to anchor the list, * hide the real ID. Only count real ecaps. XXX PCI spec diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h index facaa324bd86..bd0ae9decc00 100644 --- a/include/uapi/linux/pci_regs.h +++ b/include/uapi/linux/pci_regs.h @@ -768,6 +768,11 @@ #define PCI_EXT_CAP_DSN_SIZEOF 12 #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40 =20 +/* Device Serial Number */ +#define PCI_DSN_CAP 0x00 /* Capability header */ +#define PCI_DSN_LOW_DW 0x04 /* Serial number, lower dword */ +#define PCI_DSN_HIGH_DW 0x08 /* Serial number, upper dword */ + /* Advanced Error Reporting */ #define PCI_ERR_UNCOR_STATUS 0x04 /* Uncorrectable Error Status */ #define PCI_ERR_UNC_UND 0x00000001 /* Undefined */ --=20 2.34.1 From nobody Sat Jun 13 23:46:20 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 8C959386543 for ; Sat, 13 Jun 2026 17:43:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781372639; cv=none; b=AYRpX4YyayC2Z7Ee8MbmQNFjmvJZiKM2Yes6ObsYf5PqL0rV2c4YAxsr2IFW8SVq2Ym8YUkNh1Y5G8MRgOR5BPWAP7cW4qWQN3AXpurH6R1BqH9qEpgf4qIK9QZ82wHpc/cz1myjsVzRSYl54QLRK6paaSYieiasxdH/oZ+7jt8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781372639; c=relaxed/simple; bh=YHwSTGThUAbGeIlWR07EjajkrrALmn/koWtj/6lSdVM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Xe/IEBtrxcdFC37QjeQP7Jmc1Z8QLnXGx2bBiALF7WDnHsGAjpU/EogHFpz1n/HEOOQocWLJC+/HXgNIacxbJnxPH0/l8FBr5r+1oPPVEahS2FrjOGH9wM+HPifHkAE2cPjRlQU2E6+SnBCA0x05/Q0ZnxVH/6JdEBitaKh7Lm4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=W/49r9D7; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=MuX90qlp; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="W/49r9D7"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="MuX90qlp" Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 65DF9ZKn2770680 for ; Sat, 13 Jun 2026 17:43:57 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= MfuJ6D5x60z89yOQvwm7TqyYWGh2fB+rxO9NU6z64Q0=; b=W/49r9D784hW9NPd bes7BHETEoqD8g13JprnGNdj8+evVAoojh3OyUuaQzqvkEGCaOGxRcbFZ5aZ0CgA ZKr6FB8c58J5X2xfNqTHUXa0P7ZDITnd+15IqPAeYfHJJXHm7ZQfxTK+zcMIkd6O K9w5bVLHse2HJ5s/M239qAFanr8/TwS1eGeyMb+27FcVPZ3d6fm6p/Au0Me4Cm5k G3ySibCffSmmrHFpDzdekoMNAwRL5ODqcdwXQWx4ybfCw7DvYda055cu6AGw9q94 RnH81xfg+WgMrNeOP9fJFy3igPwyFrSpv2Wrs4/y7/1sVObnPQz5qMUbyd0hxYEh hxNV5Q== Received: from mail-pf1-f200.google.com (mail-pf1-f200.google.com [209.85.210.200]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4erye11nj1-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Sat, 13 Jun 2026 17:43:56 +0000 (GMT) Received: by mail-pf1-f200.google.com with SMTP id d2e1a72fcca58-8421ffff8a3so2570622b3a.2 for ; Sat, 13 Jun 2026 10:43:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1781372636; x=1781977436; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=MfuJ6D5x60z89yOQvwm7TqyYWGh2fB+rxO9NU6z64Q0=; b=MuX90qlpYk4ft4iFux3YOWy80R4OuNbkzPhaQ5i1iiBfdwd5TX7fWOoBuG9BR26IyL AMTWWhIFLLzXn3nqJNVtKUMTCTT/KvSogeDLguIHuljwhsC1hey7OwXrJvBitctyxDSL 1pj0B1aoxVTkmG5WG5kuRwVG5PHznX9dLjVb3nUgpcIM529cMl37c8hl9hi8u4OO4Fan mbjdZUJc465Y/R7B5+yT0VCcwyrLnwlZF80Lo9a7fvj4ge+DHgZnZAOeWTdAjz6eFiG/ 3ezurgv8q9JdXVK4T9wVSFyEjHOPbEzK3S18Kgzoevp6aAZrfki0G1c3BwWX8KjYlPUv IXHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781372636; x=1781977436; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=MfuJ6D5x60z89yOQvwm7TqyYWGh2fB+rxO9NU6z64Q0=; b=J79a8LIJw83izObXr+nKTmB+YvTmJcSe5uRx4WA7aRfUwAACe+I1dbKSOTu9gLakdd lJk9PTgWguY1+LgebBbV6Ii00kiRPD2kXmK/vCinY/N2IGrgdi77StQVVlaP3p4MQAAv 55LiEABb6Dp1bs4q/u+Y4d7GxgD0D6j84qvAE8MsAHyenNElFXGjMpQHhZLHW2QemJ0F rNnpi9t11PffqA62KXW1TVsHjQ/cnIZaREKU3e98RrbNcD3DcKZsSYSRrclmjkIuBdwY 7QHgAkXuaEpP5XEPIAHthRlFywZTAEUBiyvciHABXfFZlQIs2JBwET1so5gHI8W2QdP/ 4pLA== X-Forwarded-Encrypted: i=1; AFNElJ+t5MoTQBV0sRk33gyRdwcEYxwWvKFKPObYSZozdQsdYdxpYO+3bzK9dB2BWdLl8qVR3yopl7TISGeWKHc=@vger.kernel.org X-Gm-Message-State: AOJu0YyMurQTaTf16/0EdFUMwXDnNvbN76zXuqCcaHwCwE6rVkSDtg5g 2jYX2K21fXPO3YLPJseW72U42n8vdpMhd0B4ri3agdz85WRtZ+xSW+crRDuncdCYb8xXcfLSfuT tiiNSwa/keKR2o6CdYUJsjpmi+CMSjo9s06OT1x/9mzORMgMnGoRPRBueRXkS0wWoNCI= X-Gm-Gg: Acq92OHhci5NaHK12L9IVvtz160eROEXuckQoaTV8LFySh2+dPa+FH1qVYjAPe/I/ZG c3Bm+/KCXn+FFnsGUZ5i6c8uTAbDEArZBLT8hWzDsWoVJvhm/nrNbjV22wEt3k1yC//efk98iRm b/w2skCi5yjfgtNMDvo6DQXz7cy5VsckqubUSVQAX/FQIvxxam2VyS5qtidN41Y4/wqxx8e/jc7 wNfURU4QovE8JjYPvIDSxC1lhLh3o1+1h6iE19KdUwlvrS8EyYby/z8nXqWHrwSvdC+brg0NUrK r38yEXzdRuPEX3mm+bwzsZmVUBf0YKP1jfqKr/KtVE5abf4aiDlDOAQsgoxCLrSeC7cS4HVzjgS IEFMuYxUyuVr941QDVQ8sAf3f3tzCOAr780lfeIaaXa1x2Dj1x+5sqg== X-Received: by 2002:a05:6a00:17a4:b0:82c:9e00:f958 with SMTP id d2e1a72fcca58-8434c9ce62cmr8088008b3a.0.1781372636088; Sat, 13 Jun 2026 10:43:56 -0700 (PDT) X-Received: by 2002:a05:6a00:17a4:b0:82c:9e00:f958 with SMTP id d2e1a72fcca58-8434c9ce62cmr8087982b3a.0.1781372635567; Sat, 13 Jun 2026 10:43:55 -0700 (PDT) Received: from hu-pranarya-hyd.qualcomm.com ([202.46.22.19]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8434b055095sm6594096b3a.57.2026.06.13.10.43.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 13 Jun 2026 10:43:55 -0700 (PDT) From: Pranjal Arya Date: Sat, 13 Jun 2026 23:13:37 +0530 Subject: [PATCH RFC 2/3] vfio/pci: Allow userspace to set a virtual Device Serial Number Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260613-pcie_vfio-v1-2-09168188f3f2@oss.qualcomm.com> References: <20260613-pcie_vfio-v1-0-09168188f3f2@oss.qualcomm.com> In-Reply-To: <20260613-pcie_vfio-v1-0-09168188f3f2@oss.qualcomm.com> To: Alex Williamson , Bjorn Helgaas , David Matlack , Shuah Khan Cc: linux-arm-msm@vger.kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, linux-kselftest@vger.kernel.org, Pranjal Shrivastava , Manivannan Sadhasivam , Pranjal Arya X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1781372623; l=6731; i=pranjal.arya@oss.qualcomm.com; s=20260516; h=from:subject:message-id; bh=YHwSTGThUAbGeIlWR07EjajkrrALmn/koWtj/6lSdVM=; b=q5QaIG3w1KcyGu4+OpQHu4ByqlL2Ux9nL7F71vhXzwgpASp/akqUYgl3D20lCKdlrT7ajT2nO JHG61pUlwuBBHbzaCl9POysZvJBxYNhI7iNwTsQCHSpaT02TT9YqJ0Y X-Developer-Key: i=pranjal.arya@oss.qualcomm.com; a=ed25519; pk=ymtcTlccEIDsi3ErhpjIoZZHKdPBYWGWW0Lchs5MsbE= X-Proofpoint-GUID: dQD0cD5kV5P1B7UoWxcBl-46TF-5iA4A X-Authority-Analysis: v=2.4 cv=MNlQXsZl c=1 sm=1 tr=0 ts=6a2d96dc cx=c_pps a=mDZGXZTwRPZaeRUbqKGCBw==:117 a=fChuTYTh2wq5r3m49p7fHw==:17 a=QraOWRL6XIDMBDdn:21 a=IkcTkHD0fZMA:10 a=FelO9ux0wxsA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yOCtJkima9RkubShWh1s:22 a=VwQbUJbxAAAA:8 a=Ikd4Dj_1AAAA:8 a=EUspDBNiAAAA:8 a=TAXQPXfdsw-cyHItq3cA:9 a=QEXdDO2ut3YA:10 a=zc0IvFSfCIW2DFIPzwfm:22 X-Proofpoint-Spam-Info: AW1haW4tMjYwNjEzMDE4NSBTYWx0ZWRfX2m64JJGhNufl lKScyNfEt76rAyEEqJWDmCLOXx/Wkenf2XLO+YcyQ30DjuFteyoox97vuYjxzONeAXDaStr5qg+ aIH58CvOArdnE3JwntSn+UnlOIWZbSc= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjEzMDE4NSBTYWx0ZWRfX0wBIaP38JHG4 DdcgTybp1U50nI9UmOcrdq1T0cud7h9yQ6Jn+sdzPn/pLjX5MjDCiIWl1c2ui/VO3OjEH2XsJMW horKangRoc8F3q/0JWKl2rttA6hir5IKGKx2yoLdsCjO3vdInckEYpnH1ZsJGMoXfYWYmzrrU32 VNfYqCxgKJDEm/Chug6EDpfrIoiExo75f6qoFIV52KLWlm1UIEjZp3xrp7giKZlRKOgDCN64KcH bJ/IZGvaxy/aM17/Vrq1K933hfh+wCeGWzGHy7FCyUumktYytTSCm6GZiJnJplYlC6hT156PRqx A1m6sVFxkeZ9483HshxTXLAzXod9Xu0QBreOwlqcGpvWNxKwGjtkVzGgRkXpkvSJq1FJsqsMNpl x73l6d1CvAZ7ZenPQOGRfIQfxkbAwVwqlDHSTuaOU1b0+HF5hFGFxm9aZJDFF9ao6ta0whitohT +14ndH0A+llVJQroDYA== X-Proofpoint-ORIG-GUID: dQD0cD5kV5P1B7UoWxcBl-46TF-5iA4A X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-13_03,2026-06-12_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 impostorscore=0 spamscore=0 priorityscore=1501 phishscore=0 adultscore=0 suspectscore=0 clxscore=1015 lowpriorityscore=0 bulkscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606040000 definitions=main-2606130185 The preceding patch ("vfio/pci: Virtualize and scrub Device Serial Number from guests") hides the physical PCIe Device Serial Number from guests by zeroing it. Some use cases instead need a stable but non-host-identifying serial, for example to keep a consistent device identity across live migration between different physical devices. Add a VFIO_DEVICE_FEATURE_PCI_DSN device feature that lets the trusted userspace VMM GET/SET the 64-bit serial number presented in the device's virtualized config space. SET writes the value into the virtualized DSN capability (whose dwords are virtualized by the preceding patch, so guest reads return it) and GET reads it back; PROBE reports support. The feature returns -ENOTTY for devices without a DSN capability. Guest writes remain disallowed. The presented serial is stored only in vconfig: it persists across a runtime FLR/Secondary Bus Reset (reset does not rebuild vconfig) and is cleared when the device fd is closed (vfio_config_free()), i.e. it is per-open. A feature ioctl can only reach an opened device, whose vconfig was allocated by vfio_config_init() during vfio_pci_core_enable(). This feature uses index 13, not the next sequential value 12. Index 12 is already assigned to VFIO_DEVICE_FEATURE_MIG_PRECOPY_INFOv2 in linux-next by commit d7140b5dde45 ("vfio: Define uAPI for re-init initial bytes during the PRE_COPY phase") (https://lore.kernel.org/r/20260317161753.18964-2-yishaih@nvidia.com). Using 12 makes the core feature switch route the ioctl to the migration-precopy handler, which returns -EINVAL; this was observed in testing, hence index 13. Signed-off-by: Pranjal Arya --- drivers/vfio/pci/vfio_pci_config.c | 59 ++++++++++++++++++++++++++++++++++= ++++ drivers/vfio/pci/vfio_pci_core.c | 2 ++ drivers/vfio/pci/vfio_pci_priv.h | 2 ++ include/uapi/linux/vfio.h | 18 ++++++++++++ 4 files changed, 81 insertions(+) diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci= _config.c index 24dfeb43cb71..60c19129c814 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -2078,3 +2078,62 @@ bool vfio_pci_core_range_intersect_range(loff_t buf_= start, size_t buf_cnt, return false; } EXPORT_SYMBOL_GPL(vfio_pci_core_range_intersect_range); + +int vfio_pci_core_feature_dsn(struct vfio_pci_core_device *vdev, u32 flags, + void __user *arg, size_t argsz) +{ + struct vfio_device_feature_pci_dsn dsn; + struct pci_dev *pdev =3D vdev->pdev; + __le32 *vserial; + int pos, ret; + + /* + * The DSN capability is virtualized in vconfig; locate it on the + * physical device only to decide whether the feature is supported. + * A feature ioctl can only reach an opened device, and vconfig is + * allocated by vfio_config_init() during vfio_pci_core_enable() on + * open, so vconfig is valid here. + */ + pos =3D pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_DSN); + if (!pos) + return -ENOTTY; + + ret =3D vfio_check_feature(flags, argsz, + VFIO_DEVICE_FEATURE_GET | + VFIO_DEVICE_FEATURE_SET, + sizeof(dsn)); + if (ret !=3D 1) + return ret; + + vserial =3D (__le32 *)&vdev->vconfig[pos + PCI_DSN_LOW_DW]; + + if (flags & VFIO_DEVICE_FEATURE_SET) { + if (copy_from_user(&dsn, arg, sizeof(dsn))) + return -EFAULT; + + /* + * The config-space read path (vfio_default_config_read()) + * does not hold a lock, and a guest reads the DSN as two + * 32-bit dwords. Store each dword with WRITE_ONCE() so a + * concurrent guest read observes a consistent dword; a guest + * reading the two halves around this update may see an + * old/new mix, exactly as hardware may tear a 64-bit read of + * a register pair. This matches the DSN's read-only, + * advisory nature. Serializing concurrent SET callers is the + * userspace VMM's responsibility. + */ + WRITE_ONCE(vserial[0], cpu_to_le32(lower_32_bits(dsn.serial_number))); + WRITE_ONCE(vserial[1], cpu_to_le32(upper_32_bits(dsn.serial_number))); + return 0; + } + + /* VFIO_DEVICE_FEATURE_GET */ + dsn.serial_number =3D + ((u64)le32_to_cpu(READ_ONCE(vserial[1])) << 32) | + le32_to_cpu(READ_ONCE(vserial[0])); + + if (copy_to_user(arg, &dsn, sizeof(dsn))) + return -EFAULT; + + return 0; +} diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_c= ore.c index a28f1e99362c..08a98a796717 100644 --- a/drivers/vfio/pci/vfio_pci_core.c +++ b/drivers/vfio/pci/vfio_pci_core.c @@ -1572,6 +1572,8 @@ int vfio_pci_core_ioctl_feature(struct vfio_device *d= evice, u32 flags, return vfio_pci_core_feature_token(vdev, flags, arg, argsz); case VFIO_DEVICE_FEATURE_DMA_BUF: return vfio_pci_core_feature_dma_buf(vdev, flags, arg, argsz); + case VFIO_DEVICE_FEATURE_PCI_DSN: + return vfio_pci_core_feature_dsn(vdev, flags, arg, argsz); default: return -ENOTTY; } diff --git a/drivers/vfio/pci/vfio_pci_priv.h b/drivers/vfio/pci/vfio_pci_p= riv.h index fca9d0dfac90..dfb0c800e6f1 100644 --- a/drivers/vfio/pci/vfio_pci_priv.h +++ b/drivers/vfio/pci/vfio_pci_priv.h @@ -64,6 +64,8 @@ void vfio_pci_uninit_perm_bits(void); =20 int vfio_config_init(struct vfio_pci_core_device *vdev); void vfio_config_free(struct vfio_pci_core_device *vdev); +int vfio_pci_core_feature_dsn(struct vfio_pci_core_device *vdev, u32 flags, + void __user *arg, size_t argsz); =20 int vfio_pci_set_power_state(struct vfio_pci_core_device *vdev, pci_power_t state); diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h index 5de618a3a5ee..e5b8dfd3833f 100644 --- a/include/uapi/linux/vfio.h +++ b/include/uapi/linux/vfio.h @@ -1511,6 +1511,24 @@ struct vfio_device_feature_bus_master { */ #define VFIO_DEVICE_FEATURE_DMA_BUF 11 =20 +/** + * Upon VFIO_DEVICE_FEATURE_SET, set the PCIe Device Serial Number (DSN) + * presented to the user (guest) in the device's virtualized config space. + * By default vfio-pci scrubs the physical DSN to zero so the host device's + * unique identifier is not leaked; this feature lets the hypervisor prese= nt + * a chosen, per-VM synthetic serial instead (for example a stable but + * non-host-identifying value for migration). + * + * Upon VFIO_DEVICE_FEATURE_GET, read back the currently presented serial. + * + * The feature is only available for devices that expose a DSN capability. + * serial_number is the 64-bit serial in little-endian wire order. + */ +struct vfio_device_feature_pci_dsn { + __aligned_u64 serial_number; +}; +#define VFIO_DEVICE_FEATURE_PCI_DSN 13 + struct vfio_region_dma_range { __u64 offset; __u64 length; --=20 2.34.1 From nobody Sat Jun 13 23:46:20 2026 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (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 CF30F38AC9A for ; Sat, 13 Jun 2026 17:44:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781372643; cv=none; b=XTNSq7O3NhV8rMPBD/bLjGDHvwovY8Ny3TVW60LuhMWhxe3ZX/K8AzwKpDk+MGpcZjEP6jj3E+PAsg1n8dAxQOA+JV2gGoWNH+CeL+2aNd5/31xea7Fo6BC07oUeJnHXda1srB5D9vxkDwMPcfDvzcDKZybPviGJmkpPLxeRIoA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781372643; c=relaxed/simple; bh=BDZWqkfYrsTMwtOSpaB2NdOxl/p12WNImICJVo62OTY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=ntDbnm7qOLOS2zrvxXvQKN0t49mCvya6XbnqGtK77Yg9TNvicSuGTzEPzjqGf1YbB4aI2USPOeup+VuUojdFycW77l4VSkhpM0jIo+AYzABS/b9nQJCKrE4+tAIlD7Z6xoZ+m1IVqE6/33pfk6/9QjOnRb/SNfUm+37QJcYoa8E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=YMcW+YW7; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=Jq4UX27m; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="YMcW+YW7"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="Jq4UX27m" Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 65DFQFWm2722412 for ; Sat, 13 Jun 2026 17:44:01 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= jGlZQjAgHHSL6xRUZ51BYdvPjbrtrzdJlj+7nJq97MY=; b=YMcW+YW7MQHvLjwU vNRTWhsv2fEco+19A8pN8KALS93u93EgVcWlk83dCa5jTfzP6cTus8JRkOgknca7 hrFdA/q42Cb/Ss5FGvj0TuWDPiYFJACqv7M3/7z8KWDMMA5gQMfnbyschXp1G4BM ZS8F6rSBoDjok0bhf8/v6BoXj4MTr1lrvwzob45eHQoinlJzF+JfbTWEyN4vyRdU cV0QCPLN6CbxymWHUca5zfp2PIxxdwx9RF7iXnGRKh5KAiPCR7g3Ro3Q2U62y5ge /Vb3bWNTXcuCNrmAOI19ygTDVgTgK3bBo1pS6eUEcF3QGnWGbQboXEZ0dGb0PTiR ovhibQ== Received: from mail-pg1-f197.google.com (mail-pg1-f197.google.com [209.85.215.197]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4eryybskfc-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Sat, 13 Jun 2026 17:44:00 +0000 (GMT) Received: by mail-pg1-f197.google.com with SMTP id 41be03b00d2f7-c85a2cde332so926968a12.3 for ; Sat, 13 Jun 2026 10:44:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1781372640; x=1781977440; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=jGlZQjAgHHSL6xRUZ51BYdvPjbrtrzdJlj+7nJq97MY=; b=Jq4UX27mQY9XcDRnUfiSJU3oUzT92raAQBK1CLbEUPebRTmB6B9Ohr9c9EkMo35LZ/ W4mNA9XWdqAxp/If6BJ5iMokvdxtANwjtmH1DWqshAHJVn6Mb12xRr6c60oNV/nkqlsW TOVzcKPAkVxTtKmQSmQrGAKaumoAeRNJx4y8FXaYMSBj2bAsals7ytqapE3s/4gLeqLL q8q6ek4hyTqGPkwm4AcYVgbNsdBQ/zgbOQOZ7P5Na1PT5WI6XijVxaKoLPWMrvUBrB22 zpP1aPQdjHALEvSiOXlK9OVB7GNAswNJuY4XQjchuShdC+mPqnQJfI/TElgLQ9Gbhbp5 4HlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781372640; x=1781977440; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=jGlZQjAgHHSL6xRUZ51BYdvPjbrtrzdJlj+7nJq97MY=; b=KadoUsrs3GBE3RU4GRQoigqXUscC6Bot+Fv3dZzMWlCkA0My7Dlf+vqsi14IZb52LG VFwuNDmhSuKUePetbvBELgOvt9A8Cq/xg7UY0ucspbLvZcBt3/l6ZSdMvnvbIxaBkPCi 4Pk4ev3E579BOaxEdwgE+eRp0wJd8bEHxpYYZJykyMjW82kUirXwjdF7OcxNw8Z4xcrx QF5zQ0zONJvb4FLA3LtG1ZMBlqq9vRfo+BznLcUI32f74QilHZTypAzAOL91GBmjI6rb KzCAn51clpy98bEoIeo8dRIMtO7LmskutrDz6eNNz0ROW12sznZNE/p3ZV+pm6kuUNPa 2sqw== X-Forwarded-Encrypted: i=1; AFNElJ+nmtAq03JKnguk/74mWJAprrXH0U5fquXaMCP1V4Er45ug9IyFY4ZtzI/jUbHXlH0lB/Q9qnyprtgdkXg=@vger.kernel.org X-Gm-Message-State: AOJu0YxEP1YYlfRUVKbHNfeNttKob1hxn96zUW2e+X4LIMyeKtb25BZd HBp6pGmspOwYy3zHTKneGB3Ci/7YEBzLps0yUoVvJl0b1sOtZXUmwPix475wglVkhawYVzvsb4X /D1aMi5aIzs+Pe4opkzEHfOkTcYmc1neVQl93U+CEaZTrAKj/2cKl4ujDKFc04opJmeQ= X-Gm-Gg: Acq92OFPWC+wtVXN9g33kJWg5g6+hd8U8TEhWUHLcKbOIU/qZ4R5wuviUFooEm2l5oC N3X7n05z3qdUUx2Ycu36OpzVGfgAr8ARgMgsC8HafI63ciKJPxwWoqLNC+ZBsduwykwgWBb0Kdo xmZ7xpfWGXY5K+De7AkOiKhSmTk5UCrkV5RqcMGBeUhY83gC8sajsJ2b4uHicJ0EMkuBKIkxZvg WMqavXdZ+HFr1FSf0f0zLDzSqi2cXqQqV5T2WcDEZfz3IZVTNirya2AThVBKc7fYZ0s6qjz0MCp xVS8TTLAmPD5EBk2Qytb6VP7xy0VRBvXGBaDiBBjCo/6PEVOZ323YXmBxk30vKh2qhaZy7HblGZ Aawes42+iqa9/Pnie+rIDcR6Ifiw46Pq/m6+zvXf1yLwyCVj8Z+90dg== X-Received: by 2002:a05:6a20:9f48:b0:3b4:8566:1ca4 with SMTP id adf61e73a8af0-3b783b30e0dmr9127583637.7.1781372640248; Sat, 13 Jun 2026 10:44:00 -0700 (PDT) X-Received: by 2002:a05:6a20:9f48:b0:3b4:8566:1ca4 with SMTP id adf61e73a8af0-3b783b30e0dmr9127556637.7.1781372639756; Sat, 13 Jun 2026 10:43:59 -0700 (PDT) Received: from hu-pranarya-hyd.qualcomm.com ([202.46.22.19]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8434b055095sm6594096b3a.57.2026.06.13.10.43.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 13 Jun 2026 10:43:59 -0700 (PDT) From: Pranjal Arya Date: Sat, 13 Jun 2026 23:13:38 +0530 Subject: [PATCH RFC 3/3] selftests/vfio: Add PCIe Device Serial Number test Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260613-pcie_vfio-v1-3-09168188f3f2@oss.qualcomm.com> References: <20260613-pcie_vfio-v1-0-09168188f3f2@oss.qualcomm.com> In-Reply-To: <20260613-pcie_vfio-v1-0-09168188f3f2@oss.qualcomm.com> To: Alex Williamson , Bjorn Helgaas , David Matlack , Shuah Khan Cc: linux-arm-msm@vger.kernel.org, kvm@vger.kernel.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, linux-kselftest@vger.kernel.org, Pranjal Shrivastava , Manivannan Sadhasivam , Pranjal Arya X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1781372623; l=9082; i=pranjal.arya@oss.qualcomm.com; s=20260516; h=from:subject:message-id; bh=BDZWqkfYrsTMwtOSpaB2NdOxl/p12WNImICJVo62OTY=; b=tA0YJrvTMqCrTEAv5MxC3GN8IkPZeJcJ5zXGWWHEZdAi6gAmkJvqQrup3GLGHYUA5S5CJwNIQ xsfJ3D6XYRnCB/aATY/ygUH12AHy/aOxJLAEZ2cWR8tq8UVO717hz2Q X-Developer-Key: i=pranjal.arya@oss.qualcomm.com; a=ed25519; pk=ymtcTlccEIDsi3ErhpjIoZZHKdPBYWGWW0Lchs5MsbE= X-Proofpoint-GUID: 4rVsuVs03Qv51QKV2wJJPgpnJkcACYnX X-Proofpoint-ORIG-GUID: 4rVsuVs03Qv51QKV2wJJPgpnJkcACYnX X-Proofpoint-Spam-Info: AW1haW4tMjYwNjEzMDE4NSBTYWx0ZWRfX9hqGDMTrb4wC 1bpNavUen1x65MdOIDINBYdkGughuHwr53QqK7OQBLx4UA6hOqnjV9yE0Nsb2qK9OabM/7Gw/GM eWoHY6rdk0kMcv//kDzu3A5mpcOylWw= X-Authority-Analysis: v=2.4 cv=JLYLdcKb c=1 sm=1 tr=0 ts=6a2d96e1 cx=c_pps a=rz3CxIlbcmazkYymdCej/Q==:117 a=fChuTYTh2wq5r3m49p7fHw==:17 a=IkcTkHD0fZMA:10 a=FelO9ux0wxsA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_K5XuSEh1TEqbUxoQ0s3:22 a=EUspDBNiAAAA:8 a=VwQbUJbxAAAA:8 a=Ikd4Dj_1AAAA:8 a=VokUo_5lpJzrCtGbjscA:9 a=QEXdDO2ut3YA:10 a=bFCP_H2QrGi7Okbo017w:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjEzMDE4NSBTYWx0ZWRfX4exPd3TookNS UXfZkyNNkGCOJ+3Hm8ZmkzHP8UyS1ITooIUojpR770gCJ6nkHgikzueBoIvf3LXKjj9kkAE0rGt Ct+iqB3O9WEaAYamGswtt1SxqkrWXq4ECXyjHb64tbqz7c26ucMSwboJmz6372uABKLw1Q5Hc2q liSk6VULNEcSRw9DY1zdUlJFhysVWHs39WDsUEn5AqdVB6ajOBKs2WzAM7LMyNxNLYNfYucmLZu ofryycKO8508FrGdt/ScO+btp5xlEahP849qNKsjc51/Joykel8mF2EjY7gOZ8JxmkGvy3ou2SA zhF585ix+Kv7DQgaLIHPyAUJtS/VFTJy2y1kOifqTZIBtzIdTQAlFu7EysR+xemchhK4v6yNx1K 9X02MFLNdTAhVHVz8XMucAo7CnK+fQF462PhHkEh5r3SwQh4E1Q4rBKJrvDGmqUjd7qDShesV+7 kXDROZQS6Lx9LrCkWoQ== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-13_03,2026-06-12_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 spamscore=0 impostorscore=0 bulkscore=0 adultscore=0 malwarescore=0 phishscore=0 suspectscore=0 priorityscore=1501 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606040000 definitions=main-2606130185 Add a selftest exercising the vfio-pci DSN handling: - the serial number is scrubbed to zero by default while the DSN capability remains present, - guest writes to the DSN bytes are rejected (value unchanged), - VFIO_DEVICE_FEATURE_PCI_DSN PROBE reflects DSN support, - SET/GET round-trips and is reflected in the guest-visible config space, - SET twice returns the latest value on GET, - the presented serial persists across a device reset, and - a short argsz is rejected with -EINVAL. The tests skip when the assigned device has no DSN capability or does not support reset. Run with the device assigned to vfio-pci, e.g.: VFIO_SELFTESTS_BDF=3D"0000:01:00.0" ./vfio_pci_dsn_test Exercised under QEMU with full VFIO assignment via IOMMUFD: all of the test's cases passed on x86_64 (intel-iommu) and arm64 (smmuv3) against an emulated e1000e (which implements DSN), and on x86_64 against an SR-IOV VF that implements DSN in an AER -> ARI -> DSN extended-capability chain. The SR-IOV run used a KASAN + PROVE_LOCKING kernel with no reports. Signed-off-by: Pranjal Arya --- MAINTAINERS | 6 + tools/testing/selftests/vfio/Makefile | 1 + tools/testing/selftests/vfio/vfio_pci_dsn_test.c | 206 +++++++++++++++++++= ++++ 3 files changed, 213 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 8629ed2aa82f..ed8e7df12021 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -28347,6 +28347,12 @@ L: kvm@vger.kernel.org S: Supported F: drivers/vfio/pci/nvgrace-gpu/ =20 +VFIO PCI DEVICE SERIAL NUMBER SELFTEST +M: Pranjal Arya +L: kvm@vger.kernel.org +S: Maintained +F: tools/testing/selftests/vfio/vfio_pci_dsn_test.c + VFIO PCI DEVICE SPECIFIC DRIVERS R: Jason Gunthorpe R: Yishai Hadas diff --git a/tools/testing/selftests/vfio/Makefile b/tools/testing/selftest= s/vfio/Makefile index e6e8cb52ab03..06e637573cf7 100644 --- a/tools/testing/selftests/vfio/Makefile +++ b/tools/testing/selftests/vfio/Makefile @@ -13,6 +13,7 @@ TEST_GEN_PROGS +=3D vfio_pci_device_test TEST_GEN_PROGS +=3D vfio_pci_device_init_perf_test TEST_GEN_PROGS +=3D vfio_pci_driver_test TEST_GEN_PROGS +=3D vfio_pci_sriov_uapi_test +TEST_GEN_PROGS +=3D vfio_pci_dsn_test =20 TEST_FILES +=3D scripts/cleanup.sh TEST_FILES +=3D scripts/lib.sh diff --git a/tools/testing/selftests/vfio/vfio_pci_dsn_test.c b/tools/testi= ng/selftests/vfio/vfio_pci_dsn_test.c new file mode 100644 index 000000000000..d7652ad725f4 --- /dev/null +++ b/tools/testing/selftests/vfio/vfio_pci_dsn_test.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Tests for the PCIe Device Serial Number (DSN) handling in vfio-pci: + * - the physical serial is scrubbed (read as zero) by default, + * - guest writes to the DSN bytes are rejected (no change), and + * - VFIO_DEVICE_FEATURE_PCI_DSN can probe/set/get the presented serial. + */ +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include "kselftest_harness.h" + +static const char *device_bdf; + +/* Walk the extended capability chain and return the DSN cap offset, or 0.= */ +static u16 find_dsn_cap(struct vfio_pci_device *device) +{ + u16 pos =3D PCI_CFG_SPACE_SIZE; + int loops =3D (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / + PCI_CAP_SIZEOF; + + while (pos >=3D PCI_CFG_SPACE_SIZE && loops--) { + u32 header =3D vfio_pci_config_readl(device, pos); + + if (!header) + break; + + if (PCI_EXT_CAP_ID(header) =3D=3D PCI_EXT_CAP_ID_DSN) + return pos; + + pos =3D PCI_EXT_CAP_NEXT(header); + } + + return 0; +} + +/* + * Issue the DSN device feature. @serial may be NULL for PROBE (no data is + * read or written in that case); for GET/SET it is required. + */ +static int dsn_feature(struct vfio_pci_device *device, u32 op, u64 *serial) +{ + u8 buf[sizeof(struct vfio_device_feature) + + sizeof(struct vfio_device_feature_pci_dsn)] =3D {}; + struct vfio_device_feature *feature =3D (void *)buf; + struct vfio_device_feature_pci_dsn *dsn =3D (void *)feature->data; + + feature->argsz =3D sizeof(buf); + feature->flags =3D op | VFIO_DEVICE_FEATURE_PCI_DSN; + + if ((op & VFIO_DEVICE_FEATURE_SET) && serial) + dsn->serial_number =3D *serial; + + if (ioctl(device->fd, VFIO_DEVICE_FEATURE, feature)) + return -errno; + + if ((op & VFIO_DEVICE_FEATURE_GET) && serial) + *serial =3D dsn->serial_number; + + return 0; +} + +FIXTURE(vfio_pci_dsn_test) { + struct iommu *iommu; + struct vfio_pci_device *device; + u16 dsn_pos; +}; + +FIXTURE_SETUP(vfio_pci_dsn_test) +{ + self->iommu =3D iommu_init(default_iommu_mode); + self->device =3D vfio_pci_device_init(device_bdf, self->iommu); + self->dsn_pos =3D find_dsn_cap(self->device); +} + +FIXTURE_TEARDOWN(vfio_pci_dsn_test) +{ + vfio_pci_device_cleanup(self->device); + iommu_cleanup(self->iommu); +} + +/* The physical serial number must not be visible; reads must be zero. */ +TEST_F(vfio_pci_dsn_test, serial_scrubbed) +{ + if (!self->dsn_pos) + SKIP(return, "Device has no DSN capability\n"); + + ASSERT_EQ(0, vfio_pci_config_readl(self->device, self->dsn_pos + PCI_DSN_= LOW_DW)); + ASSERT_EQ(0, vfio_pci_config_readl(self->device, self->dsn_pos + PCI_DSN_= HIGH_DW)); + + /* The capability header itself must still be present. */ + ASSERT_EQ(PCI_EXT_CAP_ID_DSN, + PCI_EXT_CAP_ID(vfio_pci_config_readl(self->device, + self->dsn_pos))); +} + +/* Guest writes to the DSN bytes must be ignored (read-only state). */ +TEST_F(vfio_pci_dsn_test, write_rejected) +{ + if (!self->dsn_pos) + SKIP(return, "Device has no DSN capability\n"); + + vfio_pci_config_writel(self->device, self->dsn_pos + PCI_DSN_LOW_DW, 0xde= adbeef); + vfio_pci_config_writel(self->device, self->dsn_pos + PCI_DSN_HIGH_DW, 0xc= afef00d); + + ASSERT_EQ(0, vfio_pci_config_readl(self->device, self->dsn_pos + PCI_DSN_= LOW_DW)); + ASSERT_EQ(0, vfio_pci_config_readl(self->device, self->dsn_pos + PCI_DSN_= HIGH_DW)); +} + +/* PROBE must succeed iff the device has a DSN capability. */ +TEST_F(vfio_pci_dsn_test, probe) +{ + /* PROBE must include at least one supported op flag to pass. */ + int ret =3D dsn_feature(self->device, + VFIO_DEVICE_FEATURE_PROBE | + VFIO_DEVICE_FEATURE_GET | + VFIO_DEVICE_FEATURE_SET, NULL); + + if (!self->dsn_pos) + ASSERT_EQ(-ENOTTY, ret); + else + ASSERT_EQ(0, ret); +} + +/* SET then GET must round-trip, and the guest-visible bytes must match. */ +TEST_F(vfio_pci_dsn_test, set_get_roundtrip) +{ + u64 want =3D 0x0123456789abcdefULL; + u64 got =3D 0; + + if (!self->dsn_pos) + SKIP(return, "Device has no DSN capability\n"); + + ASSERT_EQ(0, dsn_feature(self->device, VFIO_DEVICE_FEATURE_SET, &want)); + ASSERT_EQ(0, dsn_feature(self->device, VFIO_DEVICE_FEATURE_GET, &got)); + ASSERT_EQ(want, got); + + ASSERT_EQ((u32)want, + vfio_pci_config_readl(self->device, self->dsn_pos + PCI_DSN_LOW_DW)); + ASSERT_EQ((u32)(want >> 32), + vfio_pci_config_readl(self->device, self->dsn_pos + PCI_DSN_HIGH_DW)); +} + +/* SET twice; GET must return the latest value. */ +TEST_F(vfio_pci_dsn_test, set_twice) +{ + u64 first =3D 0x1111222233334444ULL; + u64 second =3D 0xaaaabbbbccccddddULL; + u64 got =3D 0; + + if (!self->dsn_pos) + SKIP(return, "Device has no DSN capability\n"); + + ASSERT_EQ(0, dsn_feature(self->device, VFIO_DEVICE_FEATURE_SET, &first)); + ASSERT_EQ(0, dsn_feature(self->device, VFIO_DEVICE_FEATURE_SET, &second)); + ASSERT_EQ(0, dsn_feature(self->device, VFIO_DEVICE_FEATURE_GET, &got)); + ASSERT_EQ(second, got); +} + +/* The presented serial persists across a device reset (FLR/SBR). */ +TEST_F(vfio_pci_dsn_test, persists_across_reset) +{ + u64 want =3D 0x5555666677778888ULL; + u64 got =3D 0; + + if (!self->dsn_pos) + SKIP(return, "Device has no DSN capability\n"); + if (!(self->device->info.flags & VFIO_DEVICE_FLAGS_RESET)) + SKIP(return, "Device does not support reset\n"); + + ASSERT_EQ(0, dsn_feature(self->device, VFIO_DEVICE_FEATURE_SET, &want)); + vfio_pci_device_reset(self->device); + ASSERT_EQ(0, dsn_feature(self->device, VFIO_DEVICE_FEATURE_GET, &got)); + ASSERT_EQ(want, got); +} + +/* A short argsz must be rejected with -EINVAL. */ +TEST_F(vfio_pci_dsn_test, bad_argsz) +{ + struct vfio_device_feature feature =3D { + .argsz =3D sizeof(struct vfio_device_feature), + .flags =3D VFIO_DEVICE_FEATURE_GET | VFIO_DEVICE_FEATURE_PCI_DSN, + }; + + if (!self->dsn_pos) + SKIP(return, "Device has no DSN capability\n"); + + ASSERT_EQ(-1, ioctl(self->device->fd, VFIO_DEVICE_FEATURE, &feature)); + ASSERT_EQ(EINVAL, errno); +} + +int main(int argc, char *argv[]) +{ + device_bdf =3D vfio_selftests_get_bdf(&argc, argv); + return test_harness_run(argc, argv); +} --=20 2.34.1