Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

accel/habanalabs/gaudi2: add signed dev info uAPI

User will provide a nonce via the INFO ioctl, and will retrieve
the signed device info generated using given nonce.

Signed-off-by: Moti Haimovski <mhaimovski@habana.ai>
Reviewed-by: Oded Gabbay <ogabbay@kernel.org>
Signed-off-by: Oded Gabbay <ogabbay@kernel.org>

authored by

Moti Haimovski and committed by
Oded Gabbay
7259eb7b 5bc155cf

+98 -1
+8
drivers/accel/habanalabs/common/firmware_if.c
··· 3244 3244 HL_CPUCP_SEC_ATTEST_INFO_TINEOUT_USEC); 3245 3245 } 3246 3246 3247 + int hl_fw_get_dev_info_signed(struct hl_device *hdev, 3248 + struct cpucp_dev_info_signed *dev_info_signed, u32 nonce) 3249 + { 3250 + return hl_fw_get_sec_attest_data(hdev, CPUCP_PACKET_INFO_SIGNED_GET, dev_info_signed, 3251 + sizeof(struct cpucp_dev_info_signed), nonce, 3252 + HL_CPUCP_SEC_ATTEST_INFO_TINEOUT_USEC); 3253 + } 3254 + 3247 3255 int hl_fw_send_generic_request(struct hl_device *hdev, enum hl_passthrough_type sub_opcode, 3248 3256 dma_addr_t buff, u32 *size) 3249 3257 {
+2
drivers/accel/habanalabs/common/habanalabs.h
··· 3964 3964 void hl_fw_set_max_power(struct hl_device *hdev); 3965 3965 int hl_fw_get_sec_attest_info(struct hl_device *hdev, struct cpucp_sec_attest_info *sec_attest_info, 3966 3966 u32 nonce); 3967 + int hl_fw_get_dev_info_signed(struct hl_device *hdev, 3968 + struct cpucp_dev_info_signed *dev_info_signed, u32 nonce); 3967 3969 int hl_set_voltage(struct hl_device *hdev, int sensor_index, u32 attr, long value); 3968 3970 int hl_set_current(struct hl_device *hdev, int sensor_index, u32 attr, long value); 3969 3971 int hl_set_power(struct hl_device *hdev, int sensor_index, u32 attr, long value);
+53
drivers/accel/habanalabs/common/habanalabs_ioctl.c
··· 19 19 20 20 #include <asm/msr.h> 21 21 22 + /* make sure there is space for all the signed info */ 23 + static_assert(sizeof(struct cpucp_info) <= SEC_DEV_INFO_BUF_SZ); 24 + 22 25 static u32 hl_debug_struct_size[HL_DEBUG_OP_TIMESTAMP + 1] = { 23 26 [HL_DEBUG_OP_ETR] = sizeof(struct hl_debug_params_etr), 24 27 [HL_DEBUG_OP_ETF] = sizeof(struct hl_debug_params_etf), ··· 722 719 return rc; 723 720 } 724 721 722 + static int dev_info_signed(struct hl_fpriv *hpriv, struct hl_info_args *args) 723 + { 724 + void __user *out = (void __user *) (uintptr_t) args->return_pointer; 725 + struct cpucp_dev_info_signed *dev_info_signed; 726 + struct hl_info_signed *info; 727 + u32 max_size = args->return_size; 728 + int rc; 729 + 730 + if ((!max_size) || (!out)) 731 + return -EINVAL; 732 + 733 + dev_info_signed = kzalloc(sizeof(*dev_info_signed), GFP_KERNEL); 734 + if (!dev_info_signed) 735 + return -ENOMEM; 736 + 737 + info = kzalloc(sizeof(*info), GFP_KERNEL); 738 + if (!info) { 739 + rc = -ENOMEM; 740 + goto free_dev_info_signed; 741 + } 742 + 743 + rc = hl_fw_get_dev_info_signed(hpriv->hdev, 744 + dev_info_signed, args->sec_attest_nonce); 745 + if (rc) 746 + goto free_info; 747 + 748 + info->nonce = le32_to_cpu(dev_info_signed->nonce); 749 + info->info_sig_len = dev_info_signed->info_sig_len; 750 + info->pub_data_len = le16_to_cpu(dev_info_signed->pub_data_len); 751 + info->certificate_len = le16_to_cpu(dev_info_signed->certificate_len); 752 + info->dev_info_len = sizeof(struct cpucp_info); 753 + memcpy(&info->info_sig, &dev_info_signed->info_sig, sizeof(info->info_sig)); 754 + memcpy(&info->public_data, &dev_info_signed->public_data, sizeof(info->public_data)); 755 + memcpy(&info->certificate, &dev_info_signed->certificate, sizeof(info->certificate)); 756 + memcpy(&info->dev_info, &dev_info_signed->info, info->dev_info_len); 757 + 758 + rc = copy_to_user(out, info, min_t(size_t, max_size, sizeof(*info))) ? -EFAULT : 0; 759 + 760 + free_info: 761 + kfree(info); 762 + free_dev_info_signed: 763 + kfree(dev_info_signed); 764 + 765 + return rc; 766 + } 767 + 768 + 725 769 static int eventfd_register(struct hl_fpriv *hpriv, struct hl_info_args *args) 726 770 { 727 771 int rc; ··· 1138 1088 1139 1089 case HL_INFO_FW_GENERIC_REQ: 1140 1090 return send_fw_generic_request(hdev, args); 1091 + 1092 + case HL_INFO_DEV_SIGNED: 1093 + return dev_info_signed(hpriv, args); 1141 1094 1142 1095 default: 1143 1096 dev_err(dev, "Invalid request %d\n", args->op);
+7 -1
include/linux/habanalabs/cpucp_if.h
··· 659 659 * number (nonce) provided by the host to prevent replay attacks. 660 660 * public key and certificate also provided as part of the FW response. 661 661 * 662 + * CPUCP_PACKET_INFO_SIGNED_GET - 663 + * Get the device information signed by the Trusted Platform device. 664 + * device info data is also hashed with some unique number (nonce) provided 665 + * by the host to prevent replay attacks. public key and certificate also 666 + * provided as part of the FW response. 667 + * 662 668 * CPUCP_PACKET_MONITOR_DUMP_GET - 663 669 * Get monitors registers dump from the CpuCP kernel. 664 670 * The CPU will put the registers dump in the a buffer allocated by the driver ··· 739 733 CPUCP_PACKET_ENGINE_CORE_ASID_SET, /* internal */ 740 734 CPUCP_PACKET_RESERVED2, /* not used */ 741 735 CPUCP_PACKET_SEC_ATTEST_GET, /* internal */ 742 - CPUCP_PACKET_RESERVED3, /* not used */ 736 + CPUCP_PACKET_INFO_SIGNED_GET, /* internal */ 743 737 CPUCP_PACKET_RESERVED4, /* not used */ 744 738 CPUCP_PACKET_MONITOR_DUMP_GET, /* debugfs */ 745 739 CPUCP_PACKET_RESERVED5, /* not used */
+28
include/uapi/drm/habanalabs_accel.h
··· 846 846 #define HL_INFO_HW_ERR_EVENT 36 847 847 #define HL_INFO_FW_ERR_EVENT 37 848 848 #define HL_INFO_USER_ENGINE_ERR_EVENT 38 849 + #define HL_INFO_DEV_SIGNED 40 849 850 850 851 #define HL_INFO_VERSION_MAX_LEN 128 851 852 #define HL_INFO_CARD_NAME_MAX_LEN 16 ··· 1257 1256 #define SEC_SIGNATURE_BUF_SZ 255 /* (256 - 1) 1 byte used for size */ 1258 1257 #define SEC_PUB_DATA_BUF_SZ 510 /* (512 - 2) 2 bytes used for size */ 1259 1258 #define SEC_CERTIFICATE_BUF_SZ 2046 /* (2048 - 2) 2 bytes used for size */ 1259 + #define SEC_DEV_INFO_BUF_SZ 5120 1260 1260 1261 1261 /* 1262 1262 * struct hl_info_sec_attest - attestation report of the boot ··· 1290 1288 __u8 public_data[SEC_PUB_DATA_BUF_SZ]; 1291 1289 __u8 certificate[SEC_CERTIFICATE_BUF_SZ]; 1292 1290 __u8 pad0[2]; 1291 + }; 1292 + 1293 + /* 1294 + * struct hl_info_signed - device information signed by a secured device. 1295 + * @nonce: number only used once. random number provided by host. this also passed to the quote 1296 + * command as a qualifying data. 1297 + * @pub_data_len: length of the public data (bytes) 1298 + * @certificate_len: length of the certificate (bytes) 1299 + * @info_sig_len: length of the attestation signature (bytes) 1300 + * @public_data: public key info signed info data (outPublic + name + qualifiedName) 1301 + * @certificate: certificate for the signing key 1302 + * @info_sig: signature of the info + nonce data. 1303 + * @dev_info_len: length of device info (bytes) 1304 + * @dev_info: device info as byte array. 1305 + */ 1306 + struct hl_info_signed { 1307 + __u32 nonce; 1308 + __u16 pub_data_len; 1309 + __u16 certificate_len; 1310 + __u8 info_sig_len; 1311 + __u8 public_data[SEC_PUB_DATA_BUF_SZ]; 1312 + __u8 certificate[SEC_CERTIFICATE_BUF_SZ]; 1313 + __u8 info_sig[SEC_SIGNATURE_BUF_SZ]; 1314 + __u16 dev_info_len; 1315 + __u8 dev_info[SEC_DEV_INFO_BUF_SZ]; 1316 + __u8 pad[2]; 1293 1317 }; 1294 1318 1295 1319 /**