summaryrefslogtreecommitdiff
path: root/kernel/scs.c
diff options
context:
space:
mode:
authorSami Tolvanen <samitolvanen@google.com>2020-04-27 09:00:08 -0700
committerWill Deacon <will@kernel.org>2020-05-15 16:35:49 +0100
commit628d06a48f57c36abdc2a024930212e654a501b7 (patch)
treede784916db6c4bc3c63a99efc825e0726dd4b930 /kernel/scs.c
parentd08b9f0ca6605e13dcb48f04e55a30545b3c71eb (diff)
scs: Add page accounting for shadow call stack allocations
This change adds accounting for the memory allocated for shadow stacks. Signed-off-by: Sami Tolvanen <samitolvanen@google.com> Reviewed-by: Kees Cook <keescook@chromium.org> Acked-by: Will Deacon <will@kernel.org> Signed-off-by: Will Deacon <will@kernel.org>
Diffstat (limited to 'kernel/scs.c')
-rw-r--r--kernel/scs.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/kernel/scs.c b/kernel/scs.c
index 38f8f31c9451..6d2f983ac54e 100644
--- a/kernel/scs.c
+++ b/kernel/scs.c
@@ -6,8 +6,10 @@
*/
#include <linux/kasan.h>
+#include <linux/mm.h>
#include <linux/scs.h>
#include <linux/slab.h>
+#include <linux/vmstat.h>
#include <asm/scs.h>
static struct kmem_cache *scs_cache;
@@ -40,6 +42,17 @@ void __init scs_init(void)
scs_cache = kmem_cache_create("scs_cache", SCS_SIZE, 0, 0, NULL);
}
+static struct page *__scs_page(struct task_struct *tsk)
+{
+ return virt_to_page(task_scs(tsk));
+}
+
+static void scs_account(struct task_struct *tsk, int account)
+{
+ mod_zone_page_state(page_zone(__scs_page(tsk)), NR_KERNEL_SCS_KB,
+ account * (SCS_SIZE / 1024));
+}
+
int scs_prepare(struct task_struct *tsk, int node)
{
void *s = scs_alloc(node);
@@ -49,6 +62,7 @@ int scs_prepare(struct task_struct *tsk, int node)
task_scs(tsk) = s;
task_scs_offset(tsk) = 0;
+ scs_account(tsk, 1);
return 0;
}
@@ -61,5 +75,6 @@ void scs_release(struct task_struct *tsk)
return;
WARN(scs_corrupted(tsk), "corrupted shadow stack detected when freeing task\n");
+ scs_account(tsk, -1);
scs_free(s);
}