Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/2234746/?format=api
{ "id": 2234746, "url": "http://patchwork.ozlabs.org/api/1.2/patches/2234746/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260508031710.514574-12-alistair.francis@wdc.com/", "project": { "id": 28, "url": "http://patchwork.ozlabs.org/api/1.2/projects/28/?format=api", "name": "Linux PCI development", "link_name": "linux-pci", "list_id": "linux-pci.vger.kernel.org", "list_email": "linux-pci@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260508031710.514574-12-alistair.francis@wdc.com>", "list_archive_url": null, "date": "2026-05-08T03:17:03", "name": "[11/18] lib: rspdm: Support SPDM get_version", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "19a9e94c45f5d5e58bba2f6497f147bad394ef80", "submitter": { "id": 64571, "url": "http://patchwork.ozlabs.org/api/1.2/people/64571/?format=api", "name": "Alistair Francis", "email": "alistair23@gmail.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-pci/patch/20260508031710.514574-12-alistair.francis@wdc.com/mbox/", "series": [ { "id": 503312, "url": "http://patchwork.ozlabs.org/api/1.2/series/503312/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/list/?series=503312", "date": "2026-05-08T03:16:52", "name": "lib: Rust implementation of SPDM", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/503312/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2234746/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2234746/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <linux-pci+bounces-54166-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-pci@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=a+a6o51L;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=104.64.211.4; helo=sin.lore.kernel.org;\n envelope-from=linux-pci+bounces-54166-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com\n header.b=\"a+a6o51L\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=209.85.214.178", "smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=gmail.com" ], "Received": [ "from sin.lore.kernel.org (sin.lore.kernel.org [104.64.211.4])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4gBZDC5q7Zz1yK7\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 08 May 2026 13:22:03 +1000 (AEST)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sin.lore.kernel.org (Postfix) with ESMTP id F05E1301D4A0\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 8 May 2026 03:19:19 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 184132F7AB0;\n\tFri, 8 May 2026 03:18:54 +0000 (UTC)", "from mail-pl1-f178.google.com (mail-pl1-f178.google.com\n [209.85.214.178])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id C278D2F260F\n\tfor <linux-pci@vger.kernel.org>; Fri, 8 May 2026 03:18:48 +0000 (UTC)", "by mail-pl1-f178.google.com with SMTP id\n d9443c01a7336-2baca78cfaaso8654405ad.1\n for <linux-pci@vger.kernel.org>; Thu, 07 May 2026 20:18:48 -0700 (PDT)", "from toolbx.alistair23.me ([2403:581e:fdf9:0:6209:4521:6813:45b7])\n by smtp.gmail.com with ESMTPSA id\n d9443c01a7336-2baf1eafa62sm3220685ad.74.2026.05.07.20.18.40\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Thu, 07 May 2026 20:18:46 -0700 (PDT)" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1778210332; cv=none;\n b=kYzxbzsvRAjCYycFLNivxC3/SlgPbHp6KXEQ//LMdTsfThWc9hQ/j6XVBwSfx5XCmC4LJgGpxOJGcJcEh8gBgDsmmpfCQIt2RZy4eRBmCDEzgB+X3w7OQ9OOYFZWbdmuPM1PHbG2+nZZRq2xoSVXHHSD0zO4YioCvAzppvlhxwM=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1778210332; c=relaxed/simple;\n\tbh=oxNrGjcZCazizcSxSSIR96HPVNGWilr6D9NtWMsT9rw=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=gHP1TCb0kogIWy8WJX5Jq52Mv62GCGi7Vl3XR9W0GZmP7OiaihAWg+Dz8EDiRjlwGqmCZHuJ1j3exQYwUma5jtC2rPyvUfB7Z+AZJ8eYoZ0lMFqZx4rZX3zRFZRLGvu+dQt7KO2cW0TV7DZf6wO3KYQqb7wWn2YRwhxYbu3bMx4=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com;\n spf=pass smtp.mailfrom=gmail.com;\n dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com\n header.b=a+a6o51L; arc=none smtp.client-ip=209.85.214.178", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20251104; t=1778210327; x=1778815127;\n darn=vger.kernel.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=sdaY8XVDz6HV3abuC4HHO5UewMGlDvcsArdslgC4GX0=;\n b=a+a6o51LnORkrj8YRpE5Xy8JhOmLgr/EPwjAL1nxVAAUF7J/76zW8cfLLpMBpc+jns\n XcNxlEblsg+g11U2adOV+fhOn2uS9A6CY3/bNdrFONHCmqaIAsgl0q/hr5WfpCg8bM5b\n 6vf/vijWohGSxuTGnjTDAbGb0ACVYYMjaGSu0RObcl2b5X+i20WV80p62/qFMKtB6821\n RRr5M3CCWanHzG5v+6a+O1729SgJnff7wzrEFHwSxKZetRdHfXOAhzH2ojVYlwoIoJ2a\n 0QMvd14MRAivzBwj11Ad1oHAyb9kYXAvUf8hmH9dkE1ixQNdqyt0N1XL+SmuK+9NffPp\n NNlQ==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1778210327; x=1778815127;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=sdaY8XVDz6HV3abuC4HHO5UewMGlDvcsArdslgC4GX0=;\n b=gH3yiqP8bUhzTzz/PlBVTnytDHXbt8oNETXk6WqSIlsxk7IAZbT0FMOg4sjPCWdzgt\n Wby3L8ANBUauyLUbYBu+XUJmnNi8g2VJ9XMtbYle2tir5lTucqZmbPpYX0UKzszmHe90\n 6X1IYaw5oNWQP22ewA0YfOnHS09gu7l2VY22JA4TAMXoEOQUu+GCPZkwHp9mhvArF2+2\n nDv2f8MaGtgJzJ5KvOg8h2qLYkWy7Mv8HedxAsq6frYr9ebGfcSnDF/Y696AjIhdDt5H\n OnVTtdrK8xoh2RFak7/DYbwW7OpInGs/B85ATxGIsMMP9F5seNuFUWdwFgJbM3y03IV4\n hINA==", "X-Forwarded-Encrypted": "i=1;\n AFNElJ+/OnLlVvv65IV0Yyql99VI0yGfvTuIiaTW9DzoCj7/0VWHs3IIWeAOuWJ+WAngIZHp37NX72N3zhw=@vger.kernel.org", "X-Gm-Message-State": "AOJu0Yx7P/iHwSYl1bpdzKhx2xUiQPL1b92xeQXNVojnk0J/AFue+Cwx\n\tKVownEdsEZkw1zGb7Iw+SMxBMrJkWUkNozDhXREXTUbTWTyAfmEiwkJx", "X-Gm-Gg": "Acq92OGlDslE4wmuLKwaKaKxe3jiSkcs+JZdU41t08M5G6f8Erg/huNW8mtVtBpVVps\n\tbnh/+2y6GIt6po3JGuDzVBSR9Htn1GVrIKu4beA+tKi8xO9Lo1gnjkiMgoe/fCRgm+Im6F/AgKw\n\t7rH70bTz7JiJzGqIW7ZLd+A/foUq9En6L2bCKu1FtuhSFGqD+o5XMTN3F3C+XU19cqG+Xame+Lk\n\tmi8mX7/94C0N98QgYdpBQnug3DXERt2Zr8V59dMHT3JJ/jmejNcbyQJC/gmUwqUt0MKb0KV19Te\n\tmt0KUF7od3+wtDtJHxtjhbTnoDNjJqb5608OPnB4FRgQd8dmnYSQ7rKTzEnNQBAZeP9IWuhBhAD\n\tYfo9v9ekbotsu5zeGlMnxSyq4M4ZrSZfhhwwiMjTv8vyHj9ulzjYnmwBFpvrxIuQNOCdCtgTMsf\n\tIiR5SzQ8NZmT4sk9Stm3QGLOK34hfjI4qDdJ9zAswk", "X-Received": "by 2002:a17:903:1af0:b0:2ad:bd4c:a5 with SMTP id\n d9443c01a7336-2ba78f63c82mr112714875ad.1.1778210327123;\n Thu, 07 May 2026 20:18:47 -0700 (PDT)", "From": "alistair23@gmail.com", "X-Google-Original-From": "alistair.francis@wdc.com", "To": "alistair@alistair23.me,\n\tlinux-kernel@vger.kernel.org,\n\tlukas@wunner.de,\n\tJonathan.Cameron@huawei.com,\n\tbhelgaas@google.com,\n\trust-for-linux@vger.kernel.org,\n\takpm@linux-foundation.org,\n\tlinux-cxl@vger.kernel.org,\n\tdjbw@kernel.org,\n\tlinux-pci@vger.kernel.org", "Cc": "alex.gaynor@gmail.com,\n\twilfred.mallawa@wdc.com,\n\tgary@garyguo.net,\n\tbjorn3_gh@protonmail.com,\n\tbenno.lossin@proton.me,\n\taliceryhl@google.com,\n\tboqun.feng@gmail.com,\n\ta.hindborg@kernel.org,\n\ttmgross@umich.edu,\n\tojeda@kernel.org,\n\talistair23@gmail.com", "Subject": "[PATCH 11/18] lib: rspdm: Support SPDM get_version", "Date": "Fri, 8 May 2026 13:17:03 +1000", "Message-ID": "<20260508031710.514574-12-alistair.francis@wdc.com>", "X-Mailer": "git-send-email 2.52.0", "In-Reply-To": "<20260508031710.514574-1-alistair.francis@wdc.com>", "References": "<20260508031710.514574-1-alistair.francis@wdc.com>", "Precedence": "bulk", "X-Mailing-List": "linux-pci@vger.kernel.org", "List-Id": "<linux-pci.vger.kernel.org>", "List-Subscribe": "<mailto:linux-pci+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-pci+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit" }, "content": "From: Alistair Francis <alistair@alistair23.me>\n\nSupport the GET_VERSION SPDM command.\n\nSigned-off-by: Alistair Francis <alistair@alistair23.me>\n---\n lib/rspdm/consts.rs | 14 +++++++++\n lib/rspdm/lib.rs | 8 ++++-\n lib/rspdm/state.rs | 61 ++++++++++++++++++++++++++++++++++++\n lib/rspdm/validator.rs | 70 ++++++++++++++++++++++++++++++++++++++++++\n 4 files changed, 152 insertions(+), 1 deletion(-)", "diff": "diff --git a/lib/rspdm/consts.rs b/lib/rspdm/consts.rs\nindex 2feddde67885..5482a0f6cee0 100644\n--- a/lib/rspdm/consts.rs\n+++ b/lib/rspdm/consts.rs\n@@ -7,10 +7,21 @@\n //! Rust implementation of the DMTF Security Protocol and Data Model (SPDM)\n //! <https://www.dmtf.org/dsp/DSP0274>\n \n+use crate::validator::SpdmHeader;\n+use core::mem;\n+\n /* SPDM versions supported by this implementation */\n pub(crate) const SPDM_VER_10: u8 = 0x10;\n+#[allow(dead_code)]\n+pub(crate) const SPDM_VER_11: u8 = 0x11;\n+#[allow(dead_code)]\n+pub(crate) const SPDM_VER_12: u8 = 0x12;\n+#[allow(dead_code)]\n+pub(crate) const SPDM_VER_13: u8 = 0x13;\n+pub(crate) const SPDM_VER_14: u8 = 0x14;\n \n pub(crate) const SPDM_MIN_VER: u8 = SPDM_VER_10;\n+pub(crate) const SPDM_MAX_VER: u8 = SPDM_VER_14;\n \n pub(crate) const SPDM_REQ: u8 = 0x80;\n pub(crate) const SPDM_ERROR: u8 = 0x7f;\n@@ -54,3 +65,6 @@ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {\n Ok(())\n }\n }\n+\n+pub(crate) const SPDM_GET_VERSION: u8 = 0x84;\n+pub(crate) const SPDM_GET_VERSION_LEN: usize = mem::size_of::<SpdmHeader>() + u8::MAX as usize;\ndiff --git a/lib/rspdm/lib.rs b/lib/rspdm/lib.rs\nindex 758d43fba5cb..1cc6c33516fb 100644\n--- a/lib/rspdm/lib.rs\n+++ b/lib/rspdm/lib.rs\n@@ -105,7 +105,13 @@\n /// Return 0 on success or a negative errno. In particular, -EPROTONOSUPPORT\n /// indicates authentication is not supported by the device.\n #[export]\n-pub unsafe extern \"C\" fn spdm_authenticate(_state_ptr: *mut spdm_state) -> c_int {\n+pub unsafe extern \"C\" fn spdm_authenticate(state_ptr: *mut spdm_state) -> c_int {\n+ let state: &mut SpdmState = unsafe { &mut (*(state_ptr as *mut SpdmState)) };\n+\n+ if let Err(e) = state.get_version() {\n+ return e.to_errno() as c_int;\n+ }\n+\n 0\n }\n \ndiff --git a/lib/rspdm/state.rs b/lib/rspdm/state.rs\nindex 18e81f24c724..26b90942b298 100644\n--- a/lib/rspdm/state.rs\n+++ b/lib/rspdm/state.rs\n@@ -8,6 +8,7 @@\n //! <https://www.dmtf.org/dsp/DSP0274>\n \n use core::ffi::c_void;\n+use core::slice::from_raw_parts_mut;\n use kernel::prelude::*;\n use kernel::{\n bindings,\n@@ -22,10 +23,14 @@\n use crate::consts::{\n SpdmErrorCode,\n SPDM_ERROR,\n+ SPDM_GET_VERSION_LEN,\n+ SPDM_MAX_VER,\n SPDM_MIN_VER,\n SPDM_REQ, //\n };\n use crate::validator::{\n+ GetVersionReq,\n+ GetVersionRsp,\n SpdmErrorRsp,\n SpdmHeader, //\n };\n@@ -232,4 +237,60 @@ pub(crate) fn spdm_exchange(\n \n Ok(length)\n }\n+\n+ /// Negotiate a supported SPDM version and store the information\n+ /// in the `SpdmState`.\n+ pub(crate) fn get_version(&mut self) -> Result<(), Error> {\n+ let mut request = GetVersionReq::default();\n+ request.version = self.version;\n+\n+ // SAFETY: `request` is repr(C) and packed, so we can convert it to a slice\n+ let request_buf = unsafe {\n+ from_raw_parts_mut(\n+ &mut request as *mut _ as *mut u8,\n+ core::mem::size_of::<GetVersionReq>(),\n+ )\n+ };\n+\n+ let mut response_vec: KVec<u8> = KVec::with_capacity(SPDM_GET_VERSION_LEN, GFP_KERNEL)?;\n+ // SAFETY: `response_vec` is SPDM_GET_VERSION_LEN length, initialised, aligned\n+ // and won't be mutated\n+ let response_buf =\n+ unsafe { from_raw_parts_mut(response_vec.as_mut_ptr(), SPDM_GET_VERSION_LEN) };\n+\n+ let rc = self.spdm_exchange(request_buf, response_buf)?;\n+\n+ // SAFETY: `rc` is the length of data read, which will be smaller\n+ // than the capacity of the vector\n+ unsafe { response_vec.inc_len(rc as usize) };\n+\n+ let response: &mut GetVersionRsp = Untrusted::new_mut(&mut response_vec).validate_mut()?;\n+\n+ let mut foundver = false;\n+ let unaligned = core::ptr::addr_of_mut!(response.version_number_entries) as *mut u16;\n+\n+ for i in 0..response.version_number_entry_count {\n+ // Creating a reference on a packed struct will result in\n+ // undefined behaviour, so we operate on the raw data directly\n+ let addr = unaligned.wrapping_add(i as usize);\n+ let alpha_version = (unsafe { core::ptr::read_unaligned::<u16>(addr) } & 0xF) as u8;\n+ let version = (unsafe { core::ptr::read_unaligned::<u16>(addr) } >> 8) as u8;\n+\n+ if alpha_version > 0 {\n+ pr_warn!(\"Alpha version {alpha_version} is unsupported\\n\");\n+ }\n+\n+ if version >= self.version && version <= SPDM_MAX_VER {\n+ self.version = version;\n+ foundver = true;\n+ }\n+ }\n+\n+ if !foundver {\n+ pr_err!(\"No common supported version\\n\");\n+ to_result(-(bindings::EPROTO as i32))?;\n+ }\n+\n+ Ok(())\n+ }\n }\ndiff --git a/lib/rspdm/validator.rs b/lib/rspdm/validator.rs\nindex 58039f532b7d..8f45bafd4d69 100644\n--- a/lib/rspdm/validator.rs\n+++ b/lib/rspdm/validator.rs\n@@ -7,6 +7,10 @@\n //! Rust implementation of the DMTF Security Protocol and Data Model (SPDM)\n //! <https://www.dmtf.org/dsp/DSP0274>\n \n+use crate::bindings::{\n+ __IncompleteArrayField,\n+ __le16, //\n+};\n use crate::consts::SpdmErrorCode;\n use core::mem;\n use kernel::prelude::*;\n@@ -21,6 +25,11 @@\n },\n };\n \n+use crate::consts::{\n+ SPDM_GET_VERSION,\n+ SPDM_MIN_VER, //\n+};\n+\n #[repr(C, packed)]\n pub(crate) struct SpdmHeader {\n pub(crate) version: u8,\n@@ -71,3 +80,64 @@ pub(crate) struct SpdmErrorRsp {\n pub(crate) error_code: SpdmErrorCode,\n pub(crate) error_data: u8,\n }\n+\n+#[repr(C, packed)]\n+pub(crate) struct GetVersionReq {\n+ pub(crate) version: u8,\n+ pub(crate) code: u8,\n+ pub(crate) param1: u8,\n+ pub(crate) param2: u8,\n+}\n+\n+impl Default for GetVersionReq {\n+ fn default() -> Self {\n+ GetVersionReq {\n+ version: 0,\n+ code: SPDM_GET_VERSION,\n+ param1: 0,\n+ param2: 0,\n+ }\n+ }\n+}\n+\n+#[repr(C, packed)]\n+pub(crate) struct GetVersionRsp {\n+ pub(crate) version: u8,\n+ pub(crate) code: u8,\n+ param1: u8,\n+ param2: u8,\n+ reserved: u8,\n+ pub(crate) version_number_entry_count: u8,\n+ pub(crate) version_number_entries: __IncompleteArrayField<__le16>,\n+}\n+\n+impl Validate<&mut Unvalidated<KVec<u8>>> for &mut GetVersionRsp {\n+ type Err = Error;\n+\n+ fn validate(unvalidated: &mut Unvalidated<KVec<u8>>) -> Result<Self, Self::Err> {\n+ let raw = unvalidated.raw_mut();\n+ if raw.len() < mem::size_of::<GetVersionRsp>() {\n+ return Err(EINVAL);\n+ }\n+\n+ let version = *(raw.get(0).ok_or(ENOMEM))? as usize;\n+ if version != SPDM_MIN_VER.into() {\n+ return Err(EINVAL);\n+ }\n+\n+ let version_number_entries = *(raw.get(5).ok_or(ENOMEM))? as usize;\n+ let total_expected_size =\n+ version_number_entries * mem::size_of::<__le16>() + mem::size_of::<GetVersionRsp>();\n+ if raw.len() < total_expected_size {\n+ return Err(EINVAL);\n+ }\n+\n+ let ptr = raw.as_mut_ptr();\n+ // CAST: `GetVersionRsp` only contains integers and has `repr(C)`.\n+ let ptr = ptr.cast::<GetVersionRsp>();\n+ // SAFETY: `ptr` came from a reference and the cast above is valid.\n+ let rsp: &mut GetVersionRsp = unsafe { &mut *ptr };\n+\n+ Ok(rsp)\n+ }\n+}\n", "prefixes": [ "11/18" ] }