mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 16:12:59 +02:00
Arm FF-A updates for v7.0
A small set of updates to the Arm FF-A driver:
1. Fix a correctness issue in NOTIFICATION_INFO_GET handling of 32-bit
firmware responses, avoiding reads from undefined register bits.
2. Improve clarity and robustness of FF-A feature checks by tying them
to explicit version requirements.
3. Ensure Rx/Tx buffers are unmapped on FF-A initialization failure to
prevent resource leaks.
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEEunHlEgbzHrJD3ZPhAEG6vDF+4pgFAmlk3M8ACgkQAEG6vDF+
4pjzhw//SApAsO4B6OlV2CVNveaclurw7kiw79uHGc0sbylkMfENOniRLhG2ahJY
VGXUYn9Sh8YrL/ir4DdxJfVtmSLdh3UKDL3+lk1+EPvdxHiRRA0wEMZctB2tbY5I
2D0r3LmvAh8jrzvu4bJzmvDNPNCcQ+mgrZp/OXD3lPLCcgsP0DadPi4+YV7st4bW
CLr0a421dCRZBiZS26wWLNfgRcM5FJ2yEOLRE7u0LjXt7QfzfmrRJAldbuiqrD8E
RL+f0KwTAhZg4O79ZmJLhdJhqMTViCIBOnNGZN8XpyVOuxLmb7m8URhayi2t2/N0
X+Dy8fxFiJuM/oX5V9LZnIQPMndDgYehqs3GCbNqbGT3X08cwthGkatma00BkA/g
q8i49Tx1n79sO6aMf6xdYU8+kJ8aljOUyb+Lza493vFXQsq7mXn7kz+QKA2ZOTH+
uJy1zKE5FPPJJLcNmEbLOEF2WqF9T6B3jQxgWS7xe67ASua56ele5bUmlRQyX6jU
RAfADXc+x8olebbbD7JXb4VgAwW1NlunvAsb/6IpSN8s8R0AycqD8PZx9z1B7VzX
3ArejqSeTKuOszES4hjbYRpAqNt5ekFxwzOL7Fp1MTJtAYvxMgmAAj91/Vkr/2BV
GyMuPCpO28joG5GJmy9fzUbIvp1+W8BZJCp8mkWnPKb7llq6eRc=
=3Qnt
-----END PGP SIGNATURE-----
gpgsig -----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmlw7sQACgkQmmx57+YA
GNmckQ//eRUjW/ZXyhvEgXOs12bQnoXUefjd92Mv5ei3Rnxe0X1v5U6+J/G337e+
ZwpbZqiNCX6O/jhhtMgUuZTC8cncmpWFO6B5Il1W1Cx13io3UJB/4zltFXwC3usy
bAz+8Nd6oGGWoLZom1RiWaH8KvMKkjN5jtHKu8Lxk6mcXc9ISYZ34zF5V78DT/UX
HEBx+opsjFsvO3zcNjEzuFH0u5v6fFrJcs3E9KVjh9rqNuE4TLLiFjGHq1equkKA
oni6HDrhsE1L71kgwUNiv8/1XrM+ccvwBvENQEg3egpTVR5uumJtq8ArTaLx/HjH
d85k7KNmz3CKpF+FUzR6wkUTLpO5aP7jr48YTZu50u9+22bYLUWoIiuwuYk4tvqY
aEB4oEs3Z3at0dmhPU2Hlgxc0PvLXDoilJXRN24b0uMTBf/JYZ1159HNogx0lmhv
2LtMIqFUUXzbIR8VuJ35jU9vLroUt/LllC+b2h73EoixkjJwEN/5K5XlxS0AOR2b
/78YmKPxIDE04+2z3wqzo2huZ0x7nh8qi7Avw8/ycDRu90lHP3jyRJciRU2WKZG+
c/VLWmzXtsWO+RoN5v4gYmBHg+AQy/klG6VagKKeuZn7K/5xBzFmqNERBj/4gRhC
dd9gcu0NAQCguCGQzDLbiKFHTzt5RxpmJNS2MqGw8CEgQiQPdME=
=yfhm
-----END PGP SIGNATURE-----
Merge tag 'ffa-updates-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux into soc/drivers
Arm FF-A updates for v7.0
A small set of updates to the Arm FF-A driver:
1. Fix a correctness issue in NOTIFICATION_INFO_GET handling of 32-bit
firmware responses, avoiding reads from undefined register bits.
2. Improve clarity and robustness of FF-A feature checks by tying them
to explicit version requirements.
3. Ensure Rx/Tx buffers are unmapped on FF-A initialization failure to
prevent resource leaks.
* tag 'ffa-updates-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux:
firmware: arm_ffa: Correct 32-bit response handling in NOTIFICATION_INFO_GET
firmware: arm_ffa: Tie FF-A version checks to specific features
firmware: arm_ffa: Unmap Rx/Tx buffers on init failure
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
7a391243d4
|
|
@ -246,6 +246,11 @@ static int ffa_features(u32 func_feat_id, u32 input_props,
|
|||
}
|
||||
|
||||
#define PARTITION_INFO_GET_RETURN_COUNT_ONLY BIT(0)
|
||||
#define FFA_SUPPORTS_GET_COUNT_ONLY(version) ((version) > FFA_VERSION_1_0)
|
||||
#define FFA_PART_INFO_HAS_SIZE_IN_RESP(version) ((version) > FFA_VERSION_1_0)
|
||||
#define FFA_PART_INFO_HAS_UUID_IN_RESP(version) ((version) > FFA_VERSION_1_0)
|
||||
#define FFA_PART_INFO_HAS_EXEC_STATE_IN_RESP(version) \
|
||||
((version) > FFA_VERSION_1_0)
|
||||
|
||||
/* buffer must be sizeof(struct ffa_partition_info) * num_partitions */
|
||||
static int
|
||||
|
|
@ -255,7 +260,7 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
|
|||
int idx, count, flags = 0, sz, buf_sz;
|
||||
ffa_value_t partition_info;
|
||||
|
||||
if (drv_info->version > FFA_VERSION_1_0 &&
|
||||
if (FFA_SUPPORTS_GET_COUNT_ONLY(drv_info->version) &&
|
||||
(!buffer || !num_partitions)) /* Just get the count for now */
|
||||
flags = PARTITION_INFO_GET_RETURN_COUNT_ONLY;
|
||||
|
||||
|
|
@ -273,12 +278,11 @@ __ffa_partition_info_get(u32 uuid0, u32 uuid1, u32 uuid2, u32 uuid3,
|
|||
|
||||
count = partition_info.a2;
|
||||
|
||||
if (drv_info->version > FFA_VERSION_1_0) {
|
||||
if (FFA_PART_INFO_HAS_SIZE_IN_RESP(drv_info->version)) {
|
||||
buf_sz = sz = partition_info.a3;
|
||||
if (sz > sizeof(*buffer))
|
||||
buf_sz = sizeof(*buffer);
|
||||
} else {
|
||||
/* FFA_VERSION_1_0 lacks size in the response */
|
||||
buf_sz = sz = 8;
|
||||
}
|
||||
|
||||
|
|
@ -981,10 +985,27 @@ static void __do_sched_recv_cb(u16 part_id, u16 vcpu, bool is_per_vcpu)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Map logical ID index to the u16 index within the packed ID list.
|
||||
*
|
||||
* For native responses (FF-A width == kernel word size), IDs are
|
||||
* tightly packed: idx -> idx.
|
||||
*
|
||||
* For 32-bit responses on a 64-bit kernel, each 64-bit register
|
||||
* contributes 4 x u16 values but only the lower 2 are defined; the
|
||||
* upper 2 are garbage. This mapping skips those upper halves:
|
||||
* 0,1,2,3,4,5,... -> 0,1,4,5,8,9,...
|
||||
*/
|
||||
static int list_idx_to_u16_idx(int idx, bool is_native_resp)
|
||||
{
|
||||
return is_native_resp ? idx : idx + 2 * (idx >> 1);
|
||||
}
|
||||
|
||||
static void ffa_notification_info_get(void)
|
||||
{
|
||||
int idx, list, max_ids, lists_cnt, ids_processed, ids_count[MAX_IDS_64];
|
||||
bool is_64b_resp;
|
||||
int ids_processed, ids_count[MAX_IDS_64];
|
||||
int idx, list, max_ids, lists_cnt;
|
||||
bool is_64b_resp, is_native_resp;
|
||||
ffa_value_t ret;
|
||||
u64 id_list;
|
||||
|
||||
|
|
@ -1001,6 +1022,7 @@ static void ffa_notification_info_get(void)
|
|||
}
|
||||
|
||||
is_64b_resp = (ret.a0 == FFA_FN64_SUCCESS);
|
||||
is_native_resp = (ret.a0 == FFA_FN_NATIVE(SUCCESS));
|
||||
|
||||
ids_processed = 0;
|
||||
lists_cnt = FIELD_GET(NOTIFICATION_INFO_GET_ID_COUNT, ret.a2);
|
||||
|
|
@ -1017,12 +1039,16 @@ static void ffa_notification_info_get(void)
|
|||
|
||||
/* Process IDs */
|
||||
for (list = 0; list < lists_cnt; list++) {
|
||||
int u16_idx;
|
||||
u16 vcpu_id, part_id, *packed_id_list = (u16 *)&ret.a3;
|
||||
|
||||
if (ids_processed >= max_ids - 1)
|
||||
break;
|
||||
|
||||
part_id = packed_id_list[ids_processed++];
|
||||
u16_idx = list_idx_to_u16_idx(ids_processed,
|
||||
is_native_resp);
|
||||
part_id = packed_id_list[u16_idx];
|
||||
ids_processed++;
|
||||
|
||||
if (ids_count[list] == 1) { /* Global Notification */
|
||||
__do_sched_recv_cb(part_id, 0, false);
|
||||
|
|
@ -1034,7 +1060,10 @@ static void ffa_notification_info_get(void)
|
|||
if (ids_processed >= max_ids - 1)
|
||||
break;
|
||||
|
||||
vcpu_id = packed_id_list[ids_processed++];
|
||||
u16_idx = list_idx_to_u16_idx(ids_processed,
|
||||
is_native_resp);
|
||||
vcpu_id = packed_id_list[u16_idx];
|
||||
ids_processed++;
|
||||
|
||||
__do_sched_recv_cb(part_id, vcpu_id, true);
|
||||
}
|
||||
|
|
@ -1706,7 +1735,7 @@ static int ffa_setup_partitions(void)
|
|||
struct ffa_device *ffa_dev;
|
||||
struct ffa_partition_info *pbuf, *tpbuf;
|
||||
|
||||
if (drv_info->version == FFA_VERSION_1_0) {
|
||||
if (!FFA_PART_INFO_HAS_UUID_IN_RESP(drv_info->version)) {
|
||||
ret = bus_register_notifier(&ffa_bus_type, &ffa_bus_nb);
|
||||
if (ret)
|
||||
pr_err("Failed to register FF-A bus notifiers\n");
|
||||
|
|
@ -1733,7 +1762,7 @@ static int ffa_setup_partitions(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (drv_info->version > FFA_VERSION_1_0 &&
|
||||
if (FFA_PART_INFO_HAS_EXEC_STATE_IN_RESP(drv_info->version) &&
|
||||
!(tpbuf->properties & FFA_PARTITION_AARCH64_EXEC))
|
||||
ffa_mode_32bit_set(ffa_dev);
|
||||
|
||||
|
|
@ -2068,6 +2097,7 @@ static int __init ffa_init(void)
|
|||
|
||||
pr_err("failed to setup partitions\n");
|
||||
ffa_notifications_cleanup();
|
||||
ffa_rxtx_unmap(drv_info->vm_id);
|
||||
free_pages:
|
||||
if (drv_info->tx_buffer)
|
||||
free_pages_exact(drv_info->tx_buffer, rxtx_bufsz);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user