mirror of
https://github.com/torvalds/linux.git
synced 2026-05-26 16:12:59 +02:00
Apple SoC RTKit IPC library updates for 6.15:
- Additional logging for errors - A few minor improvements and bugfixes required for drivers that are yet to be upstreamed -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQS3vz815OHsEaWy0u9EEX0kKnUe6QUCZ8RBIAAKCRBEEX0kKnUe 6emXAQCKv1KH1fh1U3mUmqKFj6GNd3Ezq5uQqSwQi5gU+AgiHwD6A+vgMJ322tZ2 aHxf2QfdO+RRiJulac1kcvhkBDnp2AI= =05ee -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEiK/NIGsWEZVxh/FrYKtH/8kJUicFAmfJygcACgkQYKtH/8kJ UicY+w/+M+B5pdTN7GbbdXolV1/oZ9p+1MsQKa1aQRsUzZSu/6ALtQ36O1fJLe98 AsxP07x+PTCmROGFn9XqeLKvJ9e1k6w9kCj60aNo6Rt7FtR9VjGOS5muDws2zib0 Mu3MssXJY22M9Saf3X3lM0n1aJ0kOXd1owuOnGOx3ecZlVuUPg1JI/90R751zmxJ Qg3bMiEpRJfIdKCUgMmM1Y50XHv6QhF/RDjA/f3xl8uEW7BurRgGKrkCCoKkjNpZ znNgW6z4TRRS/zYL+0E3bJepk4rPZLLHndioCzDrUimxuf/TYAstcDTj+RepxJcc JymVi/noTLxCVDwrqvSSD4roC78sT5clbclbZo4huPhWCkL0CDG0WLQC/EfcRYF0 SatsFvLVuaKTFQ0U4NxdfpSZz0oqNyfDSGbjMdSESeIaCqRvc5UjHUL5O2ZHiI8J Th9c+pMp70ipNPdjdB7P63gGK4LDm8DkPfuu7BvXF4c1f80O5uiU1hJIPnl5eDYM DnJG9m3NhDz4KtzLFcTUvhpDoLCNxMrDhUlril9M9zl2E/zxqljdUOTGWWFnBtKk 0n1PWPXUstTFgLQ9AfHNE2WyJmxc0+WckKkxtK+JU29YswIXXRsn1N7JM+9X6BXG rojto59eevcsYbnpXBIpSFeOs2NeSZMLu1kFidqQSRebbCburNk= =QUAr -----END PGP SIGNATURE----- Merge tag 'asahi-soc-rtkit-6.15' of https://github.com/AsahiLinux/linux into soc/drivers Apple SoC RTKit IPC library updates for 6.15: - Additional logging for errors - A few minor improvements and bugfixes required for drivers that are yet to be upstreamed * tag 'asahi-soc-rtkit-6.15' of https://github.com/AsahiLinux/linux: soc: apple: rtkit: Cut syslog messages after the first '\0' soc: apple: rtkit: Use high prio work queue soc: apple: rtkit: Implement OSLog buffers properly soc: apple: rtkit: Add and use PWR_STATE_INIT instead of _ON soc: apple: rtkit: Fix use-after-free in apple_rtkit_crashlog_rx() soc: apple: rtkit: Pass the crashlog to the crashed() callback soc: apple: rtkit: Check & log more failures Link: https://lore.kernel.org/r/20250302113842.58092-1-sven@svenpeter.dev Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
c339956727
|
|
@ -221,7 +221,7 @@ static unsigned int apple_nvme_queue_depth(struct apple_nvme_queue *q)
|
|||
return APPLE_ANS_MAX_QUEUE_DEPTH;
|
||||
}
|
||||
|
||||
static void apple_nvme_rtkit_crashed(void *cookie)
|
||||
static void apple_nvme_rtkit_crashed(void *cookie, const void *crashlog, size_t crashlog_size)
|
||||
{
|
||||
struct apple_nvme *anv = cookie;
|
||||
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ struct apple_rtkit {
|
|||
|
||||
struct apple_rtkit_shmem ioreport_buffer;
|
||||
struct apple_rtkit_shmem crashlog_buffer;
|
||||
struct apple_rtkit_shmem oslog_buffer;
|
||||
|
||||
struct apple_rtkit_shmem syslog_buffer;
|
||||
char *syslog_msg_buffer;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ enum {
|
|||
APPLE_RTKIT_PWR_STATE_IDLE = 0x201, /* sleeping, retain state */
|
||||
APPLE_RTKIT_PWR_STATE_QUIESCED = 0x10, /* running but no communication */
|
||||
APPLE_RTKIT_PWR_STATE_ON = 0x20, /* normal operating state */
|
||||
APPLE_RTKIT_PWR_STATE_INIT = 0x220, /* init after starting the coproc */
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
@ -66,8 +67,9 @@ enum {
|
|||
#define APPLE_RTKIT_SYSLOG_MSG_SIZE GENMASK_ULL(31, 24)
|
||||
|
||||
#define APPLE_RTKIT_OSLOG_TYPE GENMASK_ULL(63, 56)
|
||||
#define APPLE_RTKIT_OSLOG_INIT 1
|
||||
#define APPLE_RTKIT_OSLOG_ACK 3
|
||||
#define APPLE_RTKIT_OSLOG_BUFFER_REQUEST 1
|
||||
#define APPLE_RTKIT_OSLOG_SIZE GENMASK_ULL(55, 36)
|
||||
#define APPLE_RTKIT_OSLOG_IOVA GENMASK_ULL(35, 0)
|
||||
|
||||
#define APPLE_RTKIT_MIN_SUPPORTED_VERSION 11
|
||||
#define APPLE_RTKIT_MAX_SUPPORTED_VERSION 12
|
||||
|
|
@ -97,12 +99,19 @@ bool apple_rtkit_is_crashed(struct apple_rtkit *rtk)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(apple_rtkit_is_crashed);
|
||||
|
||||
static void apple_rtkit_management_send(struct apple_rtkit *rtk, u8 type,
|
||||
static int apple_rtkit_management_send(struct apple_rtkit *rtk, u8 type,
|
||||
u64 msg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
msg &= ~APPLE_RTKIT_MGMT_TYPE;
|
||||
msg |= FIELD_PREP(APPLE_RTKIT_MGMT_TYPE, type);
|
||||
apple_rtkit_send_message(rtk, APPLE_RTKIT_EP_MGMT, msg, NULL, false);
|
||||
ret = apple_rtkit_send_message(rtk, APPLE_RTKIT_EP_MGMT, msg, NULL, false);
|
||||
|
||||
if (ret)
|
||||
dev_err(rtk->dev, "RTKit: Failed to send management message: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void apple_rtkit_management_rx_hello(struct apple_rtkit *rtk, u64 msg)
|
||||
|
|
@ -251,15 +260,21 @@ static int apple_rtkit_common_rx_get_buffer(struct apple_rtkit *rtk,
|
|||
struct apple_rtkit_shmem *buffer,
|
||||
u8 ep, u64 msg)
|
||||
{
|
||||
size_t n_4kpages = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_SIZE, msg);
|
||||
u64 reply;
|
||||
int err;
|
||||
|
||||
/* The different size vs. IOVA shifts look odd but are indeed correct this way */
|
||||
if (ep == APPLE_RTKIT_EP_OSLOG) {
|
||||
buffer->size = FIELD_GET(APPLE_RTKIT_OSLOG_SIZE, msg);
|
||||
buffer->iova = FIELD_GET(APPLE_RTKIT_OSLOG_IOVA, msg) << 12;
|
||||
} else {
|
||||
buffer->size = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_SIZE, msg) << 12;
|
||||
buffer->iova = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_IOVA, msg);
|
||||
}
|
||||
|
||||
buffer->buffer = NULL;
|
||||
buffer->iomem = NULL;
|
||||
buffer->is_mapped = false;
|
||||
buffer->iova = FIELD_GET(APPLE_RTKIT_BUFFER_REQUEST_IOVA, msg);
|
||||
buffer->size = n_4kpages << 12;
|
||||
|
||||
dev_dbg(rtk->dev, "RTKit: buffer request for 0x%zx bytes at %pad\n",
|
||||
buffer->size, &buffer->iova);
|
||||
|
|
@ -284,17 +299,30 @@ static int apple_rtkit_common_rx_get_buffer(struct apple_rtkit *rtk,
|
|||
}
|
||||
|
||||
if (!buffer->is_mapped) {
|
||||
reply = FIELD_PREP(APPLE_RTKIT_SYSLOG_TYPE,
|
||||
APPLE_RTKIT_BUFFER_REQUEST);
|
||||
reply |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_SIZE, n_4kpages);
|
||||
reply |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_IOVA,
|
||||
buffer->iova);
|
||||
/* oslog uses different fields and needs a shifted IOVA instead of size */
|
||||
if (ep == APPLE_RTKIT_EP_OSLOG) {
|
||||
reply = FIELD_PREP(APPLE_RTKIT_OSLOG_TYPE,
|
||||
APPLE_RTKIT_OSLOG_BUFFER_REQUEST);
|
||||
reply |= FIELD_PREP(APPLE_RTKIT_OSLOG_SIZE, buffer->size);
|
||||
reply |= FIELD_PREP(APPLE_RTKIT_OSLOG_IOVA,
|
||||
buffer->iova >> 12);
|
||||
} else {
|
||||
reply = FIELD_PREP(APPLE_RTKIT_SYSLOG_TYPE,
|
||||
APPLE_RTKIT_BUFFER_REQUEST);
|
||||
reply |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_SIZE,
|
||||
buffer->size >> 12);
|
||||
reply |= FIELD_PREP(APPLE_RTKIT_BUFFER_REQUEST_IOVA,
|
||||
buffer->iova);
|
||||
}
|
||||
apple_rtkit_send_message(rtk, ep, reply, NULL, false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
dev_err(rtk->dev, "RTKit: failed buffer request for 0x%zx bytes (%d)\n",
|
||||
buffer->size, err);
|
||||
|
||||
buffer->buffer = NULL;
|
||||
buffer->iomem = NULL;
|
||||
buffer->iova = 0;
|
||||
|
|
@ -360,7 +388,6 @@ static void apple_rtkit_crashlog_rx(struct apple_rtkit *rtk, u64 msg)
|
|||
apple_rtkit_memcpy(rtk, bfr, &rtk->crashlog_buffer, 0,
|
||||
rtk->crashlog_buffer.size);
|
||||
apple_rtkit_crashlog_dump(rtk, bfr, rtk->crashlog_buffer.size);
|
||||
kfree(bfr);
|
||||
} else {
|
||||
dev_err(rtk->dev,
|
||||
"RTKit: Couldn't allocate crashlog shadow buffer\n");
|
||||
|
|
@ -368,7 +395,9 @@ static void apple_rtkit_crashlog_rx(struct apple_rtkit *rtk, u64 msg)
|
|||
|
||||
rtk->crashed = true;
|
||||
if (rtk->ops->crashed)
|
||||
rtk->ops->crashed(rtk->cookie);
|
||||
rtk->ops->crashed(rtk->cookie, bfr, rtk->crashlog_buffer.size);
|
||||
|
||||
kfree(bfr);
|
||||
}
|
||||
|
||||
static void apple_rtkit_ioreport_rx(struct apple_rtkit *rtk, u64 msg)
|
||||
|
|
@ -448,7 +477,7 @@ static void apple_rtkit_syslog_rx_log(struct apple_rtkit *rtk, u64 msg)
|
|||
|
||||
log_context[sizeof(log_context) - 1] = 0;
|
||||
|
||||
msglen = rtk->syslog_msg_size - 1;
|
||||
msglen = strnlen(rtk->syslog_msg_buffer, rtk->syslog_msg_size - 1);
|
||||
while (msglen > 0 &&
|
||||
should_crop_syslog_char(rtk->syslog_msg_buffer[msglen - 1]))
|
||||
msglen--;
|
||||
|
|
@ -482,25 +511,18 @@ static void apple_rtkit_syslog_rx(struct apple_rtkit *rtk, u64 msg)
|
|||
}
|
||||
}
|
||||
|
||||
static void apple_rtkit_oslog_rx_init(struct apple_rtkit *rtk, u64 msg)
|
||||
{
|
||||
u64 ack;
|
||||
|
||||
dev_dbg(rtk->dev, "RTKit: oslog init: msg: 0x%llx\n", msg);
|
||||
ack = FIELD_PREP(APPLE_RTKIT_OSLOG_TYPE, APPLE_RTKIT_OSLOG_ACK);
|
||||
apple_rtkit_send_message(rtk, APPLE_RTKIT_EP_OSLOG, ack, NULL, false);
|
||||
}
|
||||
|
||||
static void apple_rtkit_oslog_rx(struct apple_rtkit *rtk, u64 msg)
|
||||
{
|
||||
u8 type = FIELD_GET(APPLE_RTKIT_OSLOG_TYPE, msg);
|
||||
|
||||
switch (type) {
|
||||
case APPLE_RTKIT_OSLOG_INIT:
|
||||
apple_rtkit_oslog_rx_init(rtk, msg);
|
||||
case APPLE_RTKIT_OSLOG_BUFFER_REQUEST:
|
||||
apple_rtkit_common_rx_get_buffer(rtk, &rtk->oslog_buffer,
|
||||
APPLE_RTKIT_EP_OSLOG, msg);
|
||||
break;
|
||||
default:
|
||||
dev_warn(rtk->dev, "RTKit: Unknown oslog message: %llx\n", msg);
|
||||
dev_warn(rtk->dev, "RTKit: Unknown oslog message: %llx\n",
|
||||
msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -588,11 +610,18 @@ int apple_rtkit_send_message(struct apple_rtkit *rtk, u8 ep, u64 message,
|
|||
.msg1 = ep,
|
||||
};
|
||||
|
||||
if (rtk->crashed)
|
||||
if (rtk->crashed) {
|
||||
dev_warn(rtk->dev,
|
||||
"RTKit: Device is crashed, cannot send message\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ep >= APPLE_RTKIT_APP_ENDPOINT_START &&
|
||||
!apple_rtkit_is_running(rtk))
|
||||
!apple_rtkit_is_running(rtk)) {
|
||||
dev_warn(rtk->dev,
|
||||
"RTKit: Endpoint 0x%02x is not running, cannot send message\n", ep);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The message will be sent with a MMIO write. We need the barrier
|
||||
|
|
@ -667,7 +696,7 @@ struct apple_rtkit *apple_rtkit_init(struct device *dev, void *cookie,
|
|||
rtk->mbox->rx = apple_rtkit_rx;
|
||||
rtk->mbox->cookie = rtk;
|
||||
|
||||
rtk->wq = alloc_ordered_workqueue("rtkit-%s", WQ_MEM_RECLAIM,
|
||||
rtk->wq = alloc_ordered_workqueue("rtkit-%s", WQ_HIGHPRI | WQ_MEM_RECLAIM,
|
||||
dev_name(rtk->dev));
|
||||
if (!rtk->wq) {
|
||||
ret = -ENOMEM;
|
||||
|
|
@ -710,6 +739,7 @@ int apple_rtkit_reinit(struct apple_rtkit *rtk)
|
|||
|
||||
apple_rtkit_free_buffer(rtk, &rtk->ioreport_buffer);
|
||||
apple_rtkit_free_buffer(rtk, &rtk->crashlog_buffer);
|
||||
apple_rtkit_free_buffer(rtk, &rtk->oslog_buffer);
|
||||
apple_rtkit_free_buffer(rtk, &rtk->syslog_buffer);
|
||||
|
||||
kfree(rtk->syslog_msg_buffer);
|
||||
|
|
@ -742,8 +772,10 @@ static int apple_rtkit_set_ap_power_state(struct apple_rtkit *rtk,
|
|||
reinit_completion(&rtk->ap_pwr_ack_completion);
|
||||
|
||||
msg = FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, state);
|
||||
apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_SET_AP_PWR_STATE,
|
||||
msg);
|
||||
ret = apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_SET_AP_PWR_STATE,
|
||||
msg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = apple_rtkit_wait_for_completion(&rtk->ap_pwr_ack_completion);
|
||||
if (ret)
|
||||
|
|
@ -763,8 +795,10 @@ static int apple_rtkit_set_iop_power_state(struct apple_rtkit *rtk,
|
|||
reinit_completion(&rtk->iop_pwr_ack_completion);
|
||||
|
||||
msg = FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, state);
|
||||
apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE,
|
||||
msg);
|
||||
ret = apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE,
|
||||
msg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = apple_rtkit_wait_for_completion(&rtk->iop_pwr_ack_completion);
|
||||
if (ret)
|
||||
|
|
@ -865,6 +899,7 @@ EXPORT_SYMBOL_GPL(apple_rtkit_quiesce);
|
|||
int apple_rtkit_wake(struct apple_rtkit *rtk)
|
||||
{
|
||||
u64 msg;
|
||||
int ret;
|
||||
|
||||
if (apple_rtkit_is_running(rtk))
|
||||
return -EINVAL;
|
||||
|
|
@ -875,9 +910,11 @@ int apple_rtkit_wake(struct apple_rtkit *rtk)
|
|||
* Use open-coded apple_rtkit_set_iop_power_state since apple_rtkit_boot
|
||||
* will wait for the completion anyway.
|
||||
*/
|
||||
msg = FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, APPLE_RTKIT_PWR_STATE_ON);
|
||||
apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE,
|
||||
msg);
|
||||
msg = FIELD_PREP(APPLE_RTKIT_MGMT_PWR_STATE, APPLE_RTKIT_PWR_STATE_INIT);
|
||||
ret = apple_rtkit_management_send(rtk, APPLE_RTKIT_MGMT_SET_IOP_PWR_STATE,
|
||||
msg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return apple_rtkit_boot(rtk);
|
||||
}
|
||||
|
|
@ -890,6 +927,7 @@ void apple_rtkit_free(struct apple_rtkit *rtk)
|
|||
|
||||
apple_rtkit_free_buffer(rtk, &rtk->ioreport_buffer);
|
||||
apple_rtkit_free_buffer(rtk, &rtk->crashlog_buffer);
|
||||
apple_rtkit_free_buffer(rtk, &rtk->oslog_buffer);
|
||||
apple_rtkit_free_buffer(rtk, &rtk->syslog_buffer);
|
||||
|
||||
kfree(rtk->syslog_msg_buffer);
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ struct apple_rtkit_shmem {
|
|||
* context.
|
||||
*/
|
||||
struct apple_rtkit_ops {
|
||||
void (*crashed)(void *cookie);
|
||||
void (*crashed)(void *cookie, const void *crashlog, size_t crashlog_size);
|
||||
void (*recv_message)(void *cookie, u8 endpoint, u64 message);
|
||||
bool (*recv_message_early)(void *cookie, u8 endpoint, u64 message);
|
||||
int (*shmem_setup)(void *cookie, struct apple_rtkit_shmem *bfr);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user