summaryrefslogtreecommitdiff
path: root/drivers/block
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-09-11 11:51:26 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-09-11 11:51:26 +0200
commitffb45b46184f54bf84d95e82df46932294b2031a (patch)
treecc199e0ec572fb2bf65fa4eb144f0e562bb34687 /drivers/block
parent5eccd39d8efa3bc8d557be50f202bbf023837eed (diff)
parenta300e35c0a4b4a38fb53742ea6e2a203c98ee523 (diff)
downloadlinux-stable-linux-rolling-stable.tar.gz
linux-stable-linux-rolling-stable.zip
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/ublk_drv.c6
-rw-r--r--drivers/block/zram/zram_drv.c27
-rw-r--r--drivers/block/zram/zram_drv.h16
3 files changed, 33 insertions, 16 deletions
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 2a22f9dc1f2f..037e08cb97ce 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -2651,6 +2651,12 @@ static int ublk_ch_mmap(struct file *filp, struct vm_area_struct *vma)
if (vma->vm_flags & VM_WRITE)
return -EPERM;
+ /*
+ * The per-queue command buffer is kernel-written ABI; prevent
+ * the daemon from upgrading to writable via mprotect().
+ */
+ vm_flags_clear(vma, VM_MAYWRITE);
+
end = UBLKSRV_CMD_BUF_OFFSET + ub->dev_info.nr_hw_queues * max_sz;
if (phys_off < UBLKSRV_CMD_BUF_OFFSET || phys_off >= end)
return -EINVAL;
diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
index f173f4c54b59..6cb44e229f1e 100644
--- a/drivers/block/zram/zram_drv.c
+++ b/drivers/block/zram/zram_drv.c
@@ -57,14 +57,12 @@ static size_t huge_class_size;
static const struct block_device_operations zram_devops;
static void slot_free(struct zram *zram, u32 index);
-#define slot_dep_map(zram, index) (&(zram)->table[(index)].dep_map)
-static void slot_lock_init(struct zram *zram, u32 index)
+static void slot_lock_init(struct zram *zram)
{
static struct lock_class_key __key;
- lockdep_init_map(slot_dep_map(zram, index), "zram->table[index].lock",
- &__key, 0);
+ lockdep_init_map(&zram->table_lock_map, "zram->table[index].lock", &__key, 0);
}
/*
@@ -83,9 +81,9 @@ static __must_check bool slot_trylock(struct zram *zram, u32 index)
{
unsigned long *lock = &zram->table[index].__lock;
- if (!test_and_set_bit_lock(ZRAM_ENTRY_LOCK, lock)) {
- mutex_acquire(slot_dep_map(zram, index), 0, 1, _RET_IP_);
- lock_acquired(slot_dep_map(zram, index), _RET_IP_);
+ if (!test_and_set_bit_lock(ZRAM_ENTRY_LOCK_BIT, lock)) {
+ mutex_acquire(&zram->table_lock_map, 0, 1, _RET_IP_);
+ lock_acquired(&zram->table_lock_map, _RET_IP_);
return true;
}
@@ -96,17 +94,17 @@ static void slot_lock(struct zram *zram, u32 index)
{
unsigned long *lock = &zram->table[index].__lock;
- mutex_acquire(slot_dep_map(zram, index), 0, 0, _RET_IP_);
- wait_on_bit_lock(lock, ZRAM_ENTRY_LOCK, TASK_UNINTERRUPTIBLE);
- lock_acquired(slot_dep_map(zram, index), _RET_IP_);
+ mutex_acquire(&zram->table_lock_map, 0, 0, _RET_IP_);
+ wait_on_bit_lock(lock, ZRAM_ENTRY_LOCK_BIT, TASK_UNINTERRUPTIBLE);
+ lock_acquired(&zram->table_lock_map, _RET_IP_);
}
static void slot_unlock(struct zram *zram, u32 index)
{
unsigned long *lock = &zram->table[index].__lock;
- mutex_release(slot_dep_map(zram, index), _RET_IP_);
- clear_and_wake_up_bit(ZRAM_ENTRY_LOCK, lock);
+ mutex_release(&zram->table_lock_map, _RET_IP_);
+ clear_and_wake_up_bit(ZRAM_ENTRY_LOCK_BIT, lock);
}
static inline bool init_done(struct zram *zram)
@@ -1989,7 +1987,7 @@ static void zram_meta_free(struct zram *zram, u64 disksize)
static bool zram_meta_alloc(struct zram *zram, u64 disksize)
{
- size_t num_pages, index;
+ size_t num_pages;
num_pages = disksize >> PAGE_SHIFT;
zram->table = vzalloc(array_size(num_pages, sizeof(*zram->table)));
@@ -2006,8 +2004,7 @@ static bool zram_meta_alloc(struct zram *zram, u64 disksize)
if (!huge_class_size)
huge_class_size = zs_huge_class_size(zram->mem_pool);
- for (index = 0; index < num_pages; index++)
- slot_lock_init(zram, index);
+ slot_lock_init(zram);
return true;
}
diff --git a/drivers/block/zram/zram_drv.h b/drivers/block/zram/zram_drv.h
index 08d1774c15db..996bb99ea8bb 100644
--- a/drivers/block/zram/zram_drv.h
+++ b/drivers/block/zram/zram_drv.h
@@ -15,6 +15,7 @@
#ifndef _ZRAM_DRV_H_
#define _ZRAM_DRV_H_
+#include <asm/byteorder.h>
#include <linux/rwsem.h>
#include <linux/zsmalloc.h>
@@ -58,6 +59,19 @@ enum zram_pageflags {
};
/*
+ * The slot lock is a bit-wait lock on the whole __lock word, while
+ * flags and ac_time alias that word as two u32s. The lock bit must
+ * land in the slot that ZRAM_ENTRY_LOCK reserves in attr.flags; on
+ * 64-bit big-endian the flags word maps to the upper half of __lock,
+ * so the bit position has to be shifted up.
+ */
+#if defined(CONFIG_64BIT) && defined(__BIG_ENDIAN)
+#define ZRAM_ENTRY_LOCK_BIT (ZRAM_ENTRY_LOCK + 32)
+#else
+#define ZRAM_ENTRY_LOCK_BIT ZRAM_ENTRY_LOCK
+#endif
+
+/*
* Allocated for each disk page. We use bit-lock (ZRAM_ENTRY_LOCK bit
* of flags) to save memory. There can be plenty of entries and standard
* locking primitives (e.g. mutex) will significantly increase sizeof()
@@ -74,7 +88,6 @@ struct zram_table_entry {
#endif
} attr;
};
- struct lockdep_map dep_map;
};
struct zram_stats {
@@ -107,6 +120,7 @@ struct zram_stats {
struct zram {
struct zram_table_entry *table;
+ struct lockdep_map table_lock_map;
struct zs_pool *mem_pool;
struct zcomp *comps[ZRAM_MAX_COMPS];
struct zcomp_params params[ZRAM_MAX_COMPS];