soc: qcom: pil: track secure pages used by pil

PIL secures pages are using direct scm call, mark these pages using a magic
flag so that it can be easily identified.

add one check for removing carve out pages, that's already excluded.

Change-Id: If75ab6b4537323e7202c1dd52e2e6677cb61e437
Signed-off-by: Zhenhua Huang <zhenhuah@codeaurora.org>
This commit is contained in:
Zhenhua Huang 2020-07-04 12:34:57 +08:00
commit 8ec15472ef
3 changed files with 69 additions and 41 deletions

View file

@ -100,45 +100,6 @@ struct pil_seg {
bool relocated;
};
/**
* struct pil_priv - Private state for a pil_desc
* @proxy: work item used to run the proxy unvoting routine
* @ws: wakeup source to prevent suspend during pil_boot
* @wname: name of @ws
* @desc: pointer to pil_desc this is private data for
* @seg: list of segments sorted by physical address
* @entry_addr: physical address where processor starts booting at
* @base_addr: smallest start address among all segments that are relocatable
* @region_start: address where relocatable region starts or lowest address
* for non-relocatable images
* @region_end: address where relocatable region ends or highest address for
* non-relocatable images
* @region: region allocated for relocatable images
* @unvoted_flag: flag to keep track if we have unvoted or not.
*
* This struct contains data for a pil_desc that should not be exposed outside
* of this file. This structure points to the descriptor and the descriptor
* points to this structure so that PIL drivers can't access the private
* data of a descriptor but this file can access both.
*/
struct pil_priv {
struct delayed_work proxy;
struct wakeup_source *ws;
char wname[32];
struct pil_desc *desc;
int num_segs;
struct list_head segs;
phys_addr_t entry_addr;
phys_addr_t base_addr;
phys_addr_t region_start;
phys_addr_t region_end;
bool is_region_allocated;
struct pil_image_info __iomem *info;
int id;
int unvoted_flag;
size_t region_size;
};
/**
* struct aux_minidumpinfo - State maintained for each aux minidump entry dumped
* during SSR

View file

@ -9,9 +9,47 @@
#include <linux/mailbox/qmp.h>
#include "minidump_private.h"
#define SECURE_PAGE_MAGIC 0xEEEEEEEE
struct device;
struct module;
struct pil_priv;
/**
* struct pil_priv - Private state for a pil_desc
* @proxy: work item used to run the proxy unvoting routine
* @ws: wakeup source to prevent suspend during pil_boot
* @wname: name of @ws
* @desc: pointer to pil_desc this is private data for
* @seg: list of segments sorted by physical address
* @entry_addr: physical address where processor starts booting at
* @base_addr: smallest start address among all segments that are relocatable
* @region_start: address where relocatable region starts or lowest address
* for non-relocatable images
* @region_end: address where relocatable region ends or highest address for
* non-relocatable images
* @region: region allocated for relocatable images
* @unvoted_flag: flag to keep track if we have unvoted or not.
*
* This struct contains data for a pil_desc that should not be exposed outside
* of this file. This structure points to the descriptor and the descriptor
* points to this structure so that PIL drivers can't access the private
* data of a descriptor but this file can access both.
*/
struct pil_priv {
struct delayed_work proxy;
struct wakeup_source *ws;
char wname[32];
struct pil_desc *desc;
int num_segs;
struct list_head segs;
phys_addr_t entry_addr;
phys_addr_t base_addr;
phys_addr_t region_start;
phys_addr_t region_end;
bool is_region_allocated;
struct pil_image_info __iomem *info;
int id;
int unvoted_flag;
size_t region_size;
};
/**
* struct pil_desc - PIL descriptor

View file

@ -629,6 +629,7 @@ static int pil_auth_and_reset(struct pil_desc *pil)
struct pil_tz_data *d = desc_to_data(pil);
int rc;
u32 scm_ret = 0;
unsigned long pfn_start, pfn_end, pfn;
if (d->subsys_desc.no_auth)
return 0;
@ -647,6 +648,14 @@ static int pil_auth_and_reset(struct pil_desc *pil)
scm_ret = qcom_scm_pas_auth_and_reset(d->pas_id);
pfn_start = pil->priv->region_start >> PAGE_SHIFT;
if (pfn_valid(pfn_start) && !scm_ret) {
pfn_end = (PAGE_ALIGN(pil->priv->region_start +
pil->priv->region_size)) >> PAGE_SHIFT;
for (pfn = pfn_start; pfn < pfn_end; pfn++)
set_page_private(pfn_to_page(pfn), SECURE_PAGE_MAGIC);
}
scm_pas_disable_bw();
if (rc)
goto err_reset;
@ -665,6 +674,7 @@ static int pil_shutdown_trusted(struct pil_desc *pil)
struct pil_tz_data *d = desc_to_data(pil);
u32 scm_ret = 0;
int rc;
unsigned long pfn_start, pfn_end, pfn;
if (d->subsys_desc.no_auth)
return 0;
@ -685,6 +695,14 @@ static int pil_shutdown_trusted(struct pil_desc *pil)
scm_ret = qcom_scm_pas_shutdown(d->pas_id);
pfn_start = pil->priv->region_start >> PAGE_SHIFT;
if (pfn_valid(pfn_start) && !scm_ret) {
pfn_end = (PAGE_ALIGN(pil->priv->region_start +
pil->priv->region_size)) >> PAGE_SHIFT;
for (pfn = pfn_start; pfn < pfn_end; pfn++)
set_page_private(pfn_to_page(pfn), 0);
}
disable_unprepare_clocks(d->proxy_clks, d->proxy_clk_count);
disable_regulators(d, d->proxy_regs, d->proxy_reg_count, false);
@ -709,11 +727,22 @@ err_regulators:
static int pil_deinit_image_trusted(struct pil_desc *pil)
{
struct pil_tz_data *d = desc_to_data(pil);
u32 scm_ret = 0;
unsigned long pfn_start, pfn_end, pfn;
if (d->subsys_desc.no_auth)
return 0;
return qcom_scm_pas_shutdown(d->pas_id);
scm_ret = qcom_scm_pas_shutdown(d->pas_id);
pfn_start = pil->priv->region_start >> PAGE_SHIFT;
if (pfn_valid(pfn_start) && !scm_ret) {
pfn_end = (PAGE_ALIGN(pil->priv->region_start +
pil->priv->region_size)) >> PAGE_SHIFT;
for (pfn = pfn_start; pfn < pfn_end; pfn++)
set_page_private(pfn_to_page(pfn), 0);
}
return scm_ret;
}
static struct pil_reset_ops pil_ops_trusted = {