summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Peng <robinpeng@google.com>2023-03-06 03:16:31 +0000
committerRobin Peng <robinpeng@google.com>2023-03-06 03:16:32 +0000
commite33a3be93a092b53860d09374bfe2aca0fa4ebbb (patch)
tree429d8f6447b252c83bfcc4a36ba4398c86f24c3a
parent43a955c6a1003b3d697d4dc2b96518408e361dd1 (diff)
parentebdbc9fbe2e2afcc5bf5ac2f57e6216ab6f0f32b (diff)
downloadgs-android-gs-pantah-5.10-android13-qpr2.tar.gz
Merge SHA: ebdbc9fbe2e2a UPSTREAM: arm64: efi: Execute runtime services from a dedicated stack Bug: 267731843 Bug: 248356119 (ACK) Bug: 260821414 (ACK) Bug: 268174392 (ACK) Bug: 268574308 (ACK) Bug: 270388667 (ACK) Bug: 270683705 (ACK) Change-Id: Idf9384fc8744bc8eb069bd1a9a3de119b5817bc0 Signed-off-by: Robin Peng <robinpeng@google.com>
-rw-r--r--arch/arm64/include/asm/efi.h3
-rw-r--r--arch/arm64/kernel/efi-rt-wrapper.S14
-rw-r--r--arch/arm64/kernel/efi.c27
-rw-r--r--drivers/media/dvb-core/dmxdev.c8
-rw-r--r--fs/io_uring.c7
-rw-r--r--mm/vmscan.c3
6 files changed, 56 insertions, 6 deletions
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 973b14415271..16892f0d05ad 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -25,6 +25,7 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
({ \
efi_virtmap_load(); \
__efi_fpsimd_begin(); \
+ spin_lock(&efi_rt_lock); \
})
#define arch_efi_call_virt(p, f, args...) \
@@ -36,10 +37,12 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
#define arch_efi_call_virt_teardown() \
({ \
+ spin_unlock(&efi_rt_lock); \
__efi_fpsimd_end(); \
efi_virtmap_unload(); \
})
+extern spinlock_t efi_rt_lock;
efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);
#define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
diff --git a/arch/arm64/kernel/efi-rt-wrapper.S b/arch/arm64/kernel/efi-rt-wrapper.S
index 75691a2641c1..2d3c4b02393e 100644
--- a/arch/arm64/kernel/efi-rt-wrapper.S
+++ b/arch/arm64/kernel/efi-rt-wrapper.S
@@ -4,6 +4,7 @@
*/
#include <linux/linkage.h>
+#include <asm/assembler.h>
SYM_FUNC_START(__efi_rt_asm_wrapper)
stp x29, x30, [sp, #-32]!
@@ -16,6 +17,12 @@ SYM_FUNC_START(__efi_rt_asm_wrapper)
*/
stp x1, x18, [sp, #16]
+ ldr_l x16, efi_rt_stack_top
+ mov sp, x16
+#ifdef CONFIG_SHADOW_CALL_STACK
+ str x18, [sp, #-16]!
+#endif
+
/*
* We are lucky enough that no EFI runtime services take more than
* 5 arguments, so all are passed in registers rather than via the
@@ -29,6 +36,7 @@ SYM_FUNC_START(__efi_rt_asm_wrapper)
mov x4, x6
blr x8
+ mov sp, x29
ldp x1, x2, [sp, #16]
cmp x2, x18
ldp x29, x30, [sp], #32
@@ -42,6 +50,10 @@ SYM_FUNC_START(__efi_rt_asm_wrapper)
* called with preemption disabled and a separate shadow stack is used
* for interrupts.
*/
- mov x18, x2
+#ifdef CONFIG_SHADOW_CALL_STACK
+ ldr_l x18, efi_rt_stack_top
+ ldr x18, [x18, #-16]
+#endif
+
b efi_handle_corrupted_x18 // tail call
SYM_FUNC_END(__efi_rt_asm_wrapper)
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index fa02efb28e88..a25bdcc9e104 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -127,3 +127,30 @@ asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f)
pr_err_ratelimited(FW_BUG "register x18 corrupted by EFI %s\n", f);
return s;
}
+
+DEFINE_SPINLOCK(efi_rt_lock);
+
+asmlinkage u64 *efi_rt_stack_top __ro_after_init;
+
+/* EFI requires 8 KiB of stack space for runtime services */
+static_assert(THREAD_SIZE >= SZ_8K);
+
+static int __init arm64_efi_rt_init(void)
+{
+ void *p;
+
+ if (!efi_enabled(EFI_RUNTIME_SERVICES))
+ return 0;
+
+ p = __vmalloc_node(THREAD_SIZE, THREAD_ALIGN, GFP_KERNEL,
+ NUMA_NO_NODE, &&l);
+l: if (!p) {
+ pr_warn("Failed to allocate EFI runtime stack\n");
+ clear_bit(EFI_RUNTIME_SERVICES, &efi.flags);
+ return -ENOMEM;
+ }
+
+ efi_rt_stack_top = p + THREAD_SIZE;
+ return 0;
+}
+core_initcall(arm64_efi_rt_init);
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index e58cb8434daf..12b7f698f562 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -800,6 +800,11 @@ static int dvb_demux_open(struct inode *inode, struct file *file)
if (mutex_lock_interruptible(&dmxdev->mutex))
return -ERESTARTSYS;
+ if (dmxdev->exit) {
+ mutex_unlock(&dmxdev->mutex);
+ return -ENODEV;
+ }
+
for (i = 0; i < dmxdev->filternum; i++)
if (dmxdev->filter[i].state == DMXDEV_STATE_FREE)
break;
@@ -1458,7 +1463,10 @@ EXPORT_SYMBOL(dvb_dmxdev_init);
void dvb_dmxdev_release(struct dmxdev *dmxdev)
{
+ mutex_lock(&dmxdev->mutex);
dmxdev->exit = 1;
+ mutex_unlock(&dmxdev->mutex);
+
if (dmxdev->dvbdev->users > 1) {
wait_event(dmxdev->dvbdev->wait_queue,
dmxdev->dvbdev->users == 1);
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 5538906e47fe..35de2f1a91e6 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -8431,8 +8431,6 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx)
if (ctx->sqo_task) {
put_task_struct(ctx->sqo_task);
ctx->sqo_task = NULL;
- mmdrop(ctx->mm_account);
- ctx->mm_account = NULL;
}
#ifdef CONFIG_BLK_CGROUP
@@ -8451,6 +8449,11 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx)
}
#endif
+ if (ctx->mm_account) {
+ mmdrop(ctx->mm_account);
+ ctx->mm_account = NULL;
+ }
+
io_mem_free(ctx->rings);
io_mem_free(ctx->sq_sqes);
diff --git a/mm/vmscan.c b/mm/vmscan.c
index bb80ecfa2871..bec84652aecd 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -2690,9 +2690,6 @@ static int get_swappiness(struct lruvec *lruvec, struct scan_control *sc)
{
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
- if (mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH)
- return 0;
-
return mem_cgroup_swappiness(memcg);
}