1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2018-2019, Intel Corporation. */
4 #include <linux/unaligned.h>
5 #include <linux/crc32.h>
6 #include <linux/device.h>
7 #include <linux/firmware.h>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/pci.h>
11 #include <linux/pldmfw.h>
12 #include <linux/slab.h>
13 #include <linux/uuid.h>
15 #include "pldmfw_private.h"
17 /* Internal structure used to store details about the PLDM image file as it is
18 * being validated and processed.
21 struct pldmfw
*context
;
22 const struct firmware
*fw
;
24 /* current offset of firmware image */
27 struct list_head records
;
28 struct list_head components
;
30 /* PLDM Firmware Package Header */
31 const struct __pldm_header
*header
;
32 u16 total_header_size
;
34 /* length of the component bitmap */
35 u16 component_bitmap_len
;
38 /* Start of the component image information */
40 const u8
*component_start
;
42 /* Start pf the firmware device id records */
43 const u8
*record_start
;
46 /* The CRC at the end of the package header */
49 struct pldmfw_record
*matching_record
;
53 * pldm_check_fw_space - Verify that the firmware image has space left
54 * @data: pointer to private data
55 * @offset: offset to start from
56 * @length: length to check for
58 * Verify that the firmware data can hold a chunk of bytes with the specified
61 * Returns: zero on success, or -EFAULT if the image does not have enough
62 * space left to fit the expected length.
65 pldm_check_fw_space(struct pldmfw_priv
*data
, size_t offset
, size_t length
)
67 size_t expected_size
= offset
+ length
;
68 struct device
*dev
= data
->context
->dev
;
70 if (data
->fw
->size
< expected_size
) {
71 dev_dbg(dev
, "Firmware file size smaller than expected. Got %zu bytes, needed %zu bytes\n",
72 data
->fw
->size
, expected_size
);
80 * pldm_move_fw_offset - Move the current firmware offset forward
81 * @data: pointer to private data
82 * @bytes_to_move: number of bytes to move the offset forward by
84 * Check that there is enough space past the current offset, and then move the
85 * offset forward by this amount.
87 * Returns: zero on success, or -EFAULT if the image is too small to fit the
91 pldm_move_fw_offset(struct pldmfw_priv
*data
, size_t bytes_to_move
)
95 err
= pldm_check_fw_space(data
, data
->offset
, bytes_to_move
);
99 data
->offset
+= bytes_to_move
;
105 * pldm_parse_header - Validate and extract details about the PLDM header
106 * @data: pointer to private data
108 * Performs initial basic verification of the PLDM image, up to the first
111 * This includes the following checks and extractions
113 * * Verify that the UUID at the start of the header matches the expected
114 * value as defined in the DSP0267 PLDM specification
115 * * Check that the revision is 0x01
116 * * Extract the total header_size and verify that the image is large enough
117 * to contain at least the length of this header
118 * * Extract the size of the component bitmap length
119 * * Extract a pointer to the start of the record area
121 * Returns: zero on success, or a negative error code on failure.
123 static int pldm_parse_header(struct pldmfw_priv
*data
)
125 const struct __pldmfw_record_area
*record_area
;
126 struct device
*dev
= data
->context
->dev
;
127 const struct __pldm_header
*header
;
131 err
= pldm_move_fw_offset(data
, sizeof(*header
));
135 header
= (const struct __pldm_header
*)data
->fw
->data
;
136 data
->header
= header
;
138 if (!uuid_equal(&header
->id
, &pldm_firmware_header_id
)) {
139 dev_dbg(dev
, "Invalid package header identifier. Expected UUID %pUB, but got %pUB\n",
140 &pldm_firmware_header_id
, &header
->id
);
144 if (header
->revision
!= PACKAGE_HEADER_FORMAT_REVISION
) {
145 dev_dbg(dev
, "Invalid package header revision. Expected revision %u but got %u\n",
146 PACKAGE_HEADER_FORMAT_REVISION
, header
->revision
);
150 data
->total_header_size
= get_unaligned_le16(&header
->size
);
151 header_size
= data
->total_header_size
- sizeof(*header
);
153 err
= pldm_check_fw_space(data
, data
->offset
, header_size
);
157 data
->component_bitmap_len
=
158 get_unaligned_le16(&header
->component_bitmap_len
);
160 if (data
->component_bitmap_len
% 8 != 0) {
161 dev_dbg(dev
, "Invalid component bitmap length. The length is %u, which is not a multiple of 8\n",
162 data
->component_bitmap_len
);
166 data
->bitmap_size
= data
->component_bitmap_len
/ 8;
168 err
= pldm_move_fw_offset(data
, header
->version_len
);
172 /* extract a pointer to the record area, which just follows the main
175 record_area
= (const struct __pldmfw_record_area
*)(data
->fw
->data
+
178 err
= pldm_move_fw_offset(data
, sizeof(*record_area
));
182 data
->record_count
= record_area
->record_count
;
183 data
->record_start
= record_area
->records
;
189 * pldm_check_desc_tlv_len - Check that the length matches expectation
190 * @data: pointer to image details
191 * @type: the descriptor type
192 * @size: the length from the descriptor header
194 * If the descriptor type is one of the documented descriptor types according
195 * to the standard, verify that the provided length matches.
197 * If the type is not recognized or is VENDOR_DEFINED, return zero.
199 * Returns: zero on success, or -EINVAL if the specified size of a standard
200 * TLV does not match the expected value defined for that TLV.
203 pldm_check_desc_tlv_len(struct pldmfw_priv
*data
, u16 type
, u16 size
)
205 struct device
*dev
= data
->context
->dev
;
209 case PLDM_DESC_ID_PCI_VENDOR_ID
:
210 case PLDM_DESC_ID_PCI_DEVICE_ID
:
211 case PLDM_DESC_ID_PCI_SUBVENDOR_ID
:
212 case PLDM_DESC_ID_PCI_SUBDEV_ID
:
215 case PLDM_DESC_ID_PCI_REVISION_ID
:
218 case PLDM_DESC_ID_PNP_VENDOR_ID
:
221 case PLDM_DESC_ID_IANA_ENTERPRISE_ID
:
222 case PLDM_DESC_ID_ACPI_VENDOR_ID
:
223 case PLDM_DESC_ID_PNP_PRODUCT_ID
:
224 case PLDM_DESC_ID_ACPI_PRODUCT_ID
:
227 case PLDM_DESC_ID_UUID
:
230 case PLDM_DESC_ID_VENDOR_DEFINED
:
233 /* Do not report an error on an unexpected TLV */
234 dev_dbg(dev
, "Found unrecognized TLV type 0x%04x\n", type
);
238 if (size
!= expected_size
) {
239 dev_dbg(dev
, "Found TLV type 0x%04x with unexpected length. Got %u bytes, but expected %u bytes\n",
240 type
, size
, expected_size
);
248 * pldm_parse_desc_tlvs - Check and skip past a number of TLVs
249 * @data: pointer to private data
250 * @record: pointer to the record this TLV belongs too
251 * @desc_count: descriptor count
253 * From the current offset, read and extract the descriptor TLVs, updating the
254 * current offset each time.
256 * Returns: zero on success, or a negative error code on failure.
259 pldm_parse_desc_tlvs(struct pldmfw_priv
*data
, struct pldmfw_record
*record
, u8 desc_count
)
261 const struct __pldmfw_desc_tlv
*__desc
;
262 const u8
*desc_start
;
265 desc_start
= data
->fw
->data
+ data
->offset
;
267 pldm_for_each_desc_tlv(i
, __desc
, desc_start
, desc_count
) {
268 struct pldmfw_desc_tlv
*desc
;
272 err
= pldm_move_fw_offset(data
, sizeof(*__desc
));
276 type
= get_unaligned_le16(&__desc
->type
);
278 /* According to DSP0267, this only includes the data field */
279 size
= get_unaligned_le16(&__desc
->size
);
281 err
= pldm_check_desc_tlv_len(data
, type
, size
);
285 /* check that we have space and move the offset forward */
286 err
= pldm_move_fw_offset(data
, size
);
290 desc
= kzalloc(sizeof(*desc
), GFP_KERNEL
);
296 desc
->data
= __desc
->data
;
298 list_add_tail(&desc
->entry
, &record
->descs
);
305 * pldm_parse_one_record - Verify size of one PLDM record
306 * @data: pointer to image details
307 * @__record: pointer to the record to check
309 * This function checks that the record size does not exceed either the size
310 * of the firmware file or the total length specified in the header section.
312 * It also verifies that the recorded length of the start of the record
313 * matches the size calculated by adding the static structure length, the
314 * component bitmap length, the version string length, the length of all
315 * descriptor TLVs, and the length of the package data.
317 * Returns: zero on success, or a negative error code on failure.
320 pldm_parse_one_record(struct pldmfw_priv
*data
,
321 const struct __pldmfw_record_info
*__record
)
323 struct pldmfw_record
*record
;
324 size_t measured_length
;
326 const u8
*bitmap_ptr
;
330 /* Make a copy and insert it into the record list */
331 record
= kzalloc(sizeof(*record
), GFP_KERNEL
);
335 INIT_LIST_HEAD(&record
->descs
);
336 list_add_tail(&record
->entry
, &data
->records
);
338 /* Then check that we have space and move the offset */
339 err
= pldm_move_fw_offset(data
, sizeof(*__record
));
343 record_len
= get_unaligned_le16(&__record
->record_len
);
344 record
->package_data_len
= get_unaligned_le16(&__record
->package_data_len
);
345 record
->version_len
= __record
->version_len
;
346 record
->version_type
= __record
->version_type
;
348 bitmap_ptr
= data
->fw
->data
+ data
->offset
;
350 /* check that we have space for the component bitmap length */
351 err
= pldm_move_fw_offset(data
, data
->bitmap_size
);
355 record
->component_bitmap_len
= data
->component_bitmap_len
;
356 record
->component_bitmap
= bitmap_zalloc(record
->component_bitmap_len
,
358 if (!record
->component_bitmap
)
361 for (i
= 0; i
< data
->bitmap_size
; i
++)
362 bitmap_set_value8(record
->component_bitmap
, bitmap_ptr
[i
], i
* 8);
364 record
->version_string
= data
->fw
->data
+ data
->offset
;
366 err
= pldm_move_fw_offset(data
, record
->version_len
);
370 /* Scan through the descriptor TLVs and find the end */
371 err
= pldm_parse_desc_tlvs(data
, record
, __record
->descriptor_count
);
375 record
->package_data
= data
->fw
->data
+ data
->offset
;
377 err
= pldm_move_fw_offset(data
, record
->package_data_len
);
381 measured_length
= data
->offset
- ((const u8
*)__record
- data
->fw
->data
);
382 if (measured_length
!= record_len
) {
383 dev_dbg(data
->context
->dev
, "Unexpected record length. Measured record length is %zu bytes, expected length is %u bytes\n",
384 measured_length
, record_len
);
392 * pldm_parse_records - Locate the start of the component area
393 * @data: pointer to private data
395 * Extract the record count, and loop through each record, searching for the
398 * Returns: zero on success, or a negative error code on failure.
400 static int pldm_parse_records(struct pldmfw_priv
*data
)
402 const struct __pldmfw_component_area
*component_area
;
403 const struct __pldmfw_record_info
*record
;
407 pldm_for_each_record(i
, record
, data
->record_start
, data
->record_count
) {
408 err
= pldm_parse_one_record(data
, record
);
413 /* Extract a pointer to the component area, which just follows the
414 * PLDM device record data.
416 component_area
= (const struct __pldmfw_component_area
*)(data
->fw
->data
+ data
->offset
);
418 err
= pldm_move_fw_offset(data
, sizeof(*component_area
));
422 data
->component_count
=
423 get_unaligned_le16(&component_area
->component_image_count
);
424 data
->component_start
= component_area
->components
;
430 * pldm_parse_components - Locate the CRC header checksum
431 * @data: pointer to private data
433 * Extract the component count, and find the pointer to the component area.
434 * Scan through each component searching for the end, which should point to
435 * the package header checksum.
437 * Extract the package header CRC and save it for verification.
439 * Returns: zero on success, or a negative error code on failure.
441 static int pldm_parse_components(struct pldmfw_priv
*data
)
443 const struct __pldmfw_component_info
*__component
;
444 struct device
*dev
= data
->context
->dev
;
445 const u8
*header_crc_ptr
;
449 pldm_for_each_component(i
, __component
, data
->component_start
, data
->component_count
) {
450 struct pldmfw_component
*component
;
453 err
= pldm_move_fw_offset(data
, sizeof(*__component
));
457 err
= pldm_move_fw_offset(data
, __component
->version_len
);
461 offset
= get_unaligned_le32(&__component
->location_offset
);
462 size
= get_unaligned_le32(&__component
->size
);
464 err
= pldm_check_fw_space(data
, offset
, size
);
468 component
= kzalloc(sizeof(*component
), GFP_KERNEL
);
472 component
->index
= i
;
473 component
->classification
= get_unaligned_le16(&__component
->classification
);
474 component
->identifier
= get_unaligned_le16(&__component
->identifier
);
475 component
->comparison_stamp
= get_unaligned_le32(&__component
->comparison_stamp
);
476 component
->options
= get_unaligned_le16(&__component
->options
);
477 component
->activation_method
= get_unaligned_le16(&__component
->activation_method
);
478 component
->version_type
= __component
->version_type
;
479 component
->version_len
= __component
->version_len
;
480 component
->version_string
= __component
->version_string
;
481 component
->component_data
= data
->fw
->data
+ offset
;
482 component
->component_size
= size
;
484 list_add_tail(&component
->entry
, &data
->components
);
487 header_crc_ptr
= data
->fw
->data
+ data
->offset
;
489 err
= pldm_move_fw_offset(data
, sizeof(data
->header_crc
));
493 /* Make sure that we reached the expected offset */
494 if (data
->offset
!= data
->total_header_size
) {
495 dev_dbg(dev
, "Invalid firmware header size. Expected %u but got %zu\n",
496 data
->total_header_size
, data
->offset
);
500 data
->header_crc
= get_unaligned_le32(header_crc_ptr
);
506 * pldm_verify_header_crc - Verify that the CRC in the header matches
507 * @data: pointer to private data
509 * Calculates the 32-bit CRC using the standard IEEE 802.3 CRC polynomial and
510 * compares it to the value stored in the header.
512 * Returns: zero on success if the CRC matches, or -EBADMSG on an invalid CRC.
514 static int pldm_verify_header_crc(struct pldmfw_priv
*data
)
516 struct device
*dev
= data
->context
->dev
;
520 /* Calculate the 32-bit CRC of the header header contents up to but
521 * not including the checksum. Note that the Linux crc32_le function
522 * does not perform an expected final XOR.
524 length
= data
->offset
- sizeof(data
->header_crc
);
525 calculated_crc
= crc32_le(~0, data
->fw
->data
, length
) ^ ~0;
527 if (calculated_crc
!= data
->header_crc
) {
528 dev_dbg(dev
, "Invalid CRC in firmware header. Got 0x%08x but expected 0x%08x\n",
529 calculated_crc
, data
->header_crc
);
537 * pldmfw_free_priv - Free memory allocated while parsing the PLDM image
538 * @data: pointer to the PLDM data structure
540 * Loops through and clears all allocated memory associated with each
541 * allocated descriptor, record, and component.
543 static void pldmfw_free_priv(struct pldmfw_priv
*data
)
545 struct pldmfw_component
*component
, *c_safe
;
546 struct pldmfw_record
*record
, *r_safe
;
547 struct pldmfw_desc_tlv
*desc
, *d_safe
;
549 list_for_each_entry_safe(component
, c_safe
, &data
->components
, entry
) {
550 list_del(&component
->entry
);
554 list_for_each_entry_safe(record
, r_safe
, &data
->records
, entry
) {
555 list_for_each_entry_safe(desc
, d_safe
, &record
->descs
, entry
) {
556 list_del(&desc
->entry
);
560 if (record
->component_bitmap
) {
561 bitmap_free(record
->component_bitmap
);
562 record
->component_bitmap
= NULL
;
565 list_del(&record
->entry
);
571 * pldm_parse_image - parse and extract details from PLDM image
572 * @data: pointer to private data
574 * Verify that the firmware file contains valid data for a PLDM firmware
575 * file. Extract useful pointers and data from the firmware file and store
576 * them in the data structure.
578 * The PLDM firmware file format is defined in DMTF DSP0267 1.0.0. Care
579 * should be taken to use get_unaligned_le* when accessing data from the
582 * Returns: zero on success, or a negative error code on failure.
584 static int pldm_parse_image(struct pldmfw_priv
*data
)
588 if (WARN_ON(!(data
->context
->dev
&& data
->fw
->data
&& data
->fw
->size
)))
591 err
= pldm_parse_header(data
);
595 err
= pldm_parse_records(data
);
599 err
= pldm_parse_components(data
);
603 return pldm_verify_header_crc(data
);
606 /* these are u32 so that we can store PCI_ANY_ID */
607 struct pldm_pci_record_id
{
610 int subsystem_vendor
;
611 int subsystem_device
;
615 * pldmfw_op_pci_match_record - Check if a PCI device matches the record
616 * @context: PLDM fw update structure
617 * @record: list of records extracted from the PLDM image
619 * Determine of the PCI device associated with this device matches the record
622 * Searches the descriptor TLVs and extracts the relevant descriptor data into
623 * a pldm_pci_record_id. This is then compared against the PCI device ID
626 * Returns: true if the device matches the record, false otherwise.
628 bool pldmfw_op_pci_match_record(struct pldmfw
*context
, struct pldmfw_record
*record
)
630 struct pci_dev
*pdev
= to_pci_dev(context
->dev
);
631 struct pldm_pci_record_id id
= {
632 .vendor
= PCI_ANY_ID
,
633 .device
= PCI_ANY_ID
,
634 .subsystem_vendor
= PCI_ANY_ID
,
635 .subsystem_device
= PCI_ANY_ID
,
637 struct pldmfw_desc_tlv
*desc
;
639 list_for_each_entry(desc
, &record
->descs
, entry
) {
643 switch (desc
->type
) {
644 case PLDM_DESC_ID_PCI_VENDOR_ID
:
647 case PLDM_DESC_ID_PCI_DEVICE_ID
:
650 case PLDM_DESC_ID_PCI_SUBVENDOR_ID
:
651 ptr
= &id
.subsystem_vendor
;
653 case PLDM_DESC_ID_PCI_SUBDEV_ID
:
654 ptr
= &id
.subsystem_device
;
657 /* Skip unrelated TLVs */
661 value
= get_unaligned_le16(desc
->data
);
662 /* A value of zero for one of the descriptors is sometimes
663 * used when the record should ignore this field when matching
664 * device. For example if the record applies to any subsystem
673 if ((id
.vendor
== PCI_ANY_ID
|| id
.vendor
== pdev
->vendor
) &&
674 (id
.device
== PCI_ANY_ID
|| id
.device
== pdev
->device
) &&
675 (id
.subsystem_vendor
== PCI_ANY_ID
|| id
.subsystem_vendor
== pdev
->subsystem_vendor
) &&
676 (id
.subsystem_device
== PCI_ANY_ID
|| id
.subsystem_device
== pdev
->subsystem_device
))
681 EXPORT_SYMBOL(pldmfw_op_pci_match_record
);
684 * pldm_find_matching_record - Find the first matching PLDM record
685 * @data: pointer to private data
687 * Search through PLDM records and find the first matching entry. It is
688 * expected that only one entry matches.
690 * Store a pointer to the matching record, if found.
692 * Returns: zero on success, or -ENOENT if no matching record is found.
694 static int pldm_find_matching_record(struct pldmfw_priv
*data
)
696 struct pldmfw_record
*record
;
698 list_for_each_entry(record
, &data
->records
, entry
) {
699 if (data
->context
->ops
->match_record(data
->context
, record
)) {
700 data
->matching_record
= record
;
709 * pldm_send_package_data - Send firmware the package data for the record
710 * @data: pointer to private data
712 * Send the package data associated with the matching record to the firmware,
713 * using the send_pkg_data operation.
715 * Returns: zero on success, or a negative error code on failure.
718 pldm_send_package_data(struct pldmfw_priv
*data
)
720 struct pldmfw_record
*record
= data
->matching_record
;
721 const struct pldmfw_ops
*ops
= data
->context
->ops
;
723 return ops
->send_package_data(data
->context
, record
->package_data
,
724 record
->package_data_len
);
728 * pldm_send_component_tables - Send component table information to firmware
729 * @data: pointer to private data
731 * Loop over each component, sending the applicable components to the firmware
732 * via the send_component_table operation.
734 * Returns: zero on success, or a negative error code on failure.
737 pldm_send_component_tables(struct pldmfw_priv
*data
)
739 unsigned long *bitmap
= data
->matching_record
->component_bitmap
;
740 struct pldmfw_component
*component
;
743 list_for_each_entry(component
, &data
->components
, entry
) {
744 u8 index
= component
->index
, transfer_flag
= 0;
746 /* Skip components which are not intended for this device */
747 if (!test_bit(index
, bitmap
))
750 /* determine whether this is the start, middle, end, or both
751 * the start and end of the component tables
753 if (index
== find_first_bit(bitmap
, data
->component_bitmap_len
))
754 transfer_flag
|= PLDM_TRANSFER_FLAG_START
;
755 if (index
== find_last_bit(bitmap
, data
->component_bitmap_len
))
756 transfer_flag
|= PLDM_TRANSFER_FLAG_END
;
758 transfer_flag
= PLDM_TRANSFER_FLAG_MIDDLE
;
760 err
= data
->context
->ops
->send_component_table(data
->context
,
771 * pldm_flash_components - Program each component to device flash
772 * @data: pointer to private data
774 * Loop through each component that is active for the matching device record,
775 * and send it to the device driver for flashing.
777 * Returns: zero on success, or a negative error code on failure.
779 static int pldm_flash_components(struct pldmfw_priv
*data
)
781 unsigned long *bitmap
= data
->matching_record
->component_bitmap
;
782 struct pldmfw_component
*component
;
785 list_for_each_entry(component
, &data
->components
, entry
) {
786 u8 index
= component
->index
;
788 /* Skip components which are not intended for this device */
789 if (!test_bit(index
, bitmap
))
792 err
= data
->context
->ops
->flash_component(data
->context
, component
);
801 * pldm_finalize_update - Finalize the device flash update
802 * @data: pointer to private data
804 * Tell the device driver to perform any remaining logic to complete the
807 * Returns: zero on success, or a PLFM_FWU error indicating the reason for
810 static int pldm_finalize_update(struct pldmfw_priv
*data
)
812 if (data
->context
->ops
->finalize_update
)
813 return data
->context
->ops
->finalize_update(data
->context
);
819 * pldmfw_flash_image - Write a PLDM-formatted firmware image to the device
820 * @context: ops and data for firmware update
821 * @fw: firmware object pointing to the relevant firmware file to program
823 * Parse the data for a given firmware file, verifying that it is a valid PLDM
824 * formatted image that matches this device.
826 * Extract the device record Package Data and Component Tables and send them
827 * to the device firmware. Extract and write the flash data for each of the
828 * components indicated in the firmware file.
830 * Returns: zero on success, or a negative error code on failure.
832 int pldmfw_flash_image(struct pldmfw
*context
, const struct firmware
*fw
)
834 struct pldmfw_priv
*data
;
837 data
= kzalloc(sizeof(*data
), GFP_KERNEL
);
841 INIT_LIST_HEAD(&data
->records
);
842 INIT_LIST_HEAD(&data
->components
);
845 data
->context
= context
;
847 err
= pldm_parse_image(data
);
849 goto out_release_data
;
851 err
= pldm_find_matching_record(data
);
853 goto out_release_data
;
855 err
= pldm_send_package_data(data
);
857 goto out_release_data
;
859 err
= pldm_send_component_tables(data
);
861 goto out_release_data
;
863 err
= pldm_flash_components(data
);
865 goto out_release_data
;
867 err
= pldm_finalize_update(data
);
870 pldmfw_free_priv(data
);
875 EXPORT_SYMBOL(pldmfw_flash_image
);
877 MODULE_AUTHOR("Jacob Keller <jacob.e.keller@intel.com>");
878 MODULE_DESCRIPTION("PLDM firmware flash update library");