mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-31 06:14:39 +01:00
Qualcomm remoteproc drivers such as qcom_q6v5_mss, which do not use the Peripheral Authentication Service (PAS), always map the MBA region before use and unmap it once the usage is complete. This behavior was introduced to avoid issues seen in the past where speculative accesses from the application processor to the MBA region after it was assigned to the remote Q6 led to an XPU violation. The issue was mitigated by unmapping the region before handing control to the remote Q6. Currently, most Qualcomm SoCs using the PAS driver run either with a standalone QHEE or the Gunyah hypervisor. In these environments, the hypervisor unmaps the Q6 memory from HLOS Stage-2 and remaps it into the Q6 Stage-2 page table. As a result, speculative accesses from HLOS cannot reach the region even if it remains mapped in HLOS Stage-1; therefore, XPU violations cannot occur. However, when the same SoC runs Linux at EL2, Linux itself must perform the unmapping to avoid such issues. It is still correct to apply this mapping/ unmapping sequence even for SoCs that run under Gunyah, so this behavior should not be conditional. Introduce qcom_pas_ctx_map() in qcom_pas.h to centralise the ioremap_wc pattern used by both qcom_q6v5_pas and qcom_mdt_pas_load, and use it in both places. Reviewed-by: Dmitry Baryshkov <[email protected]> Reviewed-by: Konrad Dybcio <[email protected]> Signed-off-by: Mukesh Ojha <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Bjorn Andersson <[email protected]>
56 lines
1.6 KiB
C
56 lines
1.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (c) 2010-2015, 2018-2019 The Linux Foundation. All rights reserved.
|
|
* Copyright (C) 2015 Linaro Ltd.
|
|
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
|
*/
|
|
|
|
#ifndef __QCOM_PAS_H
|
|
#define __QCOM_PAS_H
|
|
|
|
#include <linux/device.h>
|
|
#include <linux/err.h>
|
|
#include <linux/io.h>
|
|
#include <linux/types.h>
|
|
|
|
struct qcom_pas_context {
|
|
struct device *dev;
|
|
u32 pas_id;
|
|
phys_addr_t mem_phys;
|
|
size_t mem_size;
|
|
void *ptr;
|
|
dma_addr_t phys;
|
|
ssize_t size;
|
|
bool use_tzmem;
|
|
};
|
|
|
|
static inline void __iomem *qcom_pas_ctx_map(struct qcom_pas_context *ctx)
|
|
{
|
|
void __iomem *ptr = ioremap_wc(ctx->mem_phys, ctx->mem_size);
|
|
|
|
if (!ptr)
|
|
dev_err(ctx->dev, "unable to map memory region: %pa+%zx\n",
|
|
&ctx->mem_phys, ctx->mem_size);
|
|
return ptr;
|
|
}
|
|
|
|
bool qcom_pas_is_available(void);
|
|
struct qcom_pas_context *devm_qcom_pas_context_alloc(struct device *dev,
|
|
u32 pas_id,
|
|
phys_addr_t mem_phys,
|
|
size_t mem_size);
|
|
int qcom_pas_init_image(u32 pas_id, const void *metadata, size_t size,
|
|
struct qcom_pas_context *ctx);
|
|
struct resource_table *qcom_pas_get_rsc_table(struct qcom_pas_context *ctx,
|
|
void *input_rt, size_t input_rt_size,
|
|
size_t *output_rt_size);
|
|
int qcom_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
|
|
int qcom_pas_auth_and_reset(u32 pas_id);
|
|
int qcom_pas_prepare_and_auth_reset(struct qcom_pas_context *ctx);
|
|
int qcom_pas_set_remote_state(u32 state, u32 pas_id);
|
|
int qcom_pas_shutdown(u32 pas_id);
|
|
bool qcom_pas_supported(u32 pas_id);
|
|
void qcom_pas_metadata_release(struct qcom_pas_context *ctx);
|
|
|
|
#endif /* __QCOM_PAS_H */
|