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

Configure Feed

Select the types of activity you want to include in your feed.

scsi: firmware: xilinx: Add support for secure read/write ioctl interface

Add support for a generic ioctl read/write interface using which users
can request firmware to perform read/write operations on a protected and
secure address space.

The functionality is introduced through the means of two new IOCTL IDs
which extend the existing PM_IOCTL EEMI API:

- IOCTL_READ_REG
- IOCTL_MASK_WRITE_REG

The caller only passes the node id of the given device and an offset.
The base address is not exposed to the caller and internally retrieved
by the firmware. Firmware will enforce an access policy on the incoming
read/write request.

Signed-off-by: Izhar Ameer Shaikh <izhar.ameer.shaikh@amd.com>
Reviewed-by: Tanmay Shah <tanmay.shah@amd.com>
Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
Signed-off-by: Ajay Neeli <ajay.neeli@amd.com>
Acked-by: Senthil Nathan Thangaraj <senthilnathan.thangaraj@amd.com>
Acked-by: Michal Simek <michal.simek@amd.com>
Acked-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20251021113003.13650-3-ajay.neeli@amd.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Izhar Ameer Shaikh and committed by
Martin K. Petersen
00b3e848 754c6f53

+61
+46
drivers/firmware/xilinx/zynqmp.c
··· 1617 1617 } 1618 1618 1619 1619 /** 1620 + * zynqmp_pm_sec_read_reg - PM call to securely read from given offset 1621 + * of the node 1622 + * @node_id: Node Id of the device 1623 + * @offset: Offset to be used (20-bit) 1624 + * @ret_value: Output data read from the given offset after 1625 + * firmware access policy is successfully enforced 1626 + * 1627 + * Return: Returns 0 on success or error value on failure 1628 + */ 1629 + int zynqmp_pm_sec_read_reg(u32 node_id, u32 offset, u32 *ret_value) 1630 + { 1631 + u32 ret_payload[PAYLOAD_ARG_CNT]; 1632 + u32 count = 1; 1633 + int ret; 1634 + 1635 + if (!ret_value) 1636 + return -EINVAL; 1637 + 1638 + ret = zynqmp_pm_invoke_fn(PM_IOCTL, ret_payload, 4, node_id, IOCTL_READ_REG, 1639 + offset, count); 1640 + 1641 + *ret_value = ret_payload[1]; 1642 + 1643 + return ret; 1644 + } 1645 + EXPORT_SYMBOL_GPL(zynqmp_pm_sec_read_reg); 1646 + 1647 + /** 1648 + * zynqmp_pm_sec_mask_write_reg - PM call to securely write to given offset 1649 + * of the node 1650 + * @node_id: Node Id of the device 1651 + * @offset: Offset to be used (20-bit) 1652 + * @mask: Mask to be used 1653 + * @value: Value to be written 1654 + * 1655 + * Return: Returns 0 on success or error value on failure 1656 + */ 1657 + int zynqmp_pm_sec_mask_write_reg(const u32 node_id, const u32 offset, u32 mask, 1658 + u32 value) 1659 + { 1660 + return zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 5, node_id, IOCTL_MASK_WRITE_REG, 1661 + offset, mask, value); 1662 + } 1663 + EXPORT_SYMBOL_GPL(zynqmp_pm_sec_mask_write_reg); 1664 + 1665 + /** 1620 1666 * zynqmp_pm_set_sd_config - PM call to set value of SD config registers 1621 1667 * @node: SD node ID 1622 1668 * @config: The config type of SD registers
+15
include/linux/firmware/xlnx-zynqmp.h
··· 241 241 IOCTL_GET_FEATURE_CONFIG = 27, 242 242 /* IOCTL for Secure Read/Write Interface */ 243 243 IOCTL_READ_REG = 28, 244 + IOCTL_MASK_WRITE_REG = 29, 244 245 /* Dynamic SD/GEM configuration */ 245 246 IOCTL_SET_SD_CONFIG = 30, 246 247 IOCTL_SET_GEM_CONFIG = 31, ··· 620 619 int zynqmp_pm_is_function_supported(const u32 api_id, const u32 id); 621 620 int zynqmp_pm_set_feature_config(enum pm_feature_config_id id, u32 value); 622 621 int zynqmp_pm_get_feature_config(enum pm_feature_config_id id, u32 *payload); 622 + int zynqmp_pm_sec_read_reg(u32 node_id, u32 offset, u32 *ret_value); 623 + int zynqmp_pm_sec_mask_write_reg(const u32 node_id, const u32 offset, 624 + u32 mask, u32 value); 623 625 int zynqmp_pm_register_sgi(u32 sgi_num, u32 reset); 624 626 int zynqmp_pm_force_pwrdwn(const u32 target, 625 627 const enum zynqmp_pm_request_ack ack); ··· 916 912 const bool set_addr, 917 913 const u64 address, 918 914 const enum zynqmp_pm_request_ack ack) 915 + { 916 + return -ENODEV; 917 + } 918 + 919 + static inline int zynqmp_pm_sec_read_reg(u32 node_id, u32 offset, u32 *ret_value) 920 + { 921 + return -ENODEV; 922 + } 923 + 924 + static inline int zynqmp_pm_sec_mask_write_reg(const u32 node_id, const u32 offset, 925 + u32 mask, u32 value) 919 926 { 920 927 return -ENODEV; 921 928 }