Merge 4.5-rc4 into char-misc-next
We want those fixes in here as well. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
@@ -1400,6 +1400,21 @@ config RCU_EQS_DEBUG
|
||||
|
||||
endmenu # "RCU Debugging"
|
||||
|
||||
config DEBUG_WQ_FORCE_RR_CPU
|
||||
bool "Force round-robin CPU selection for unbound work items"
|
||||
depends on DEBUG_KERNEL
|
||||
default n
|
||||
help
|
||||
Workqueue used to implicitly guarantee that work items queued
|
||||
without explicit CPU specified are put on the local CPU. This
|
||||
guarantee is no longer true and while local CPU is still
|
||||
preferred work items may be put on foreign CPUs. Kernel
|
||||
parameter "workqueue.debug_force_rr_cpu" is added to force
|
||||
round-robin CPU selection to flush out usages which depend on the
|
||||
now broken guarantee. This config option enables the debug
|
||||
feature by default. When enabled, memory and cache locality will
|
||||
be impacted.
|
||||
|
||||
config DEBUG_BLOCK_EXT_DEVT
|
||||
bool "Force extended block device numbers and spread them"
|
||||
depends on DEBUG_KERNEL
|
||||
|
@@ -18,6 +18,8 @@ config UBSAN_SANITIZE_ALL
|
||||
This option activates instrumentation for the entire kernel.
|
||||
If you don't enable this option, you have to explicitly specify
|
||||
UBSAN_SANITIZE := y for the files/directories you want to check for UB.
|
||||
Enabling this option will get kernel image size increased
|
||||
significantly.
|
||||
|
||||
config UBSAN_ALIGNMENT
|
||||
bool "Enable checking of pointers alignment"
|
||||
@@ -25,5 +27,5 @@ config UBSAN_ALIGNMENT
|
||||
default y if !HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||
help
|
||||
This option enables detection of unaligned memory accesses.
|
||||
Enabling this option on architectures that support unalligned
|
||||
Enabling this option on architectures that support unaligned
|
||||
accesses may produce a lot of false positives.
|
||||
|
@@ -21,7 +21,7 @@
|
||||
#define ODEBUG_HASH_BITS 14
|
||||
#define ODEBUG_HASH_SIZE (1 << ODEBUG_HASH_BITS)
|
||||
|
||||
#define ODEBUG_POOL_SIZE 512
|
||||
#define ODEBUG_POOL_SIZE 1024
|
||||
#define ODEBUG_POOL_MIN_LEVEL 256
|
||||
|
||||
#define ODEBUG_CHUNK_SHIFT PAGE_SHIFT
|
||||
|
@@ -25,6 +25,7 @@ static atomic_t dump_lock = ATOMIC_INIT(-1);
|
||||
|
||||
asmlinkage __visible void dump_stack(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
int was_locked;
|
||||
int old;
|
||||
int cpu;
|
||||
@@ -33,9 +34,8 @@ asmlinkage __visible void dump_stack(void)
|
||||
* Permit this cpu to perform nested stack dumps while serialising
|
||||
* against other CPUs
|
||||
*/
|
||||
preempt_disable();
|
||||
|
||||
retry:
|
||||
local_irq_save(flags);
|
||||
cpu = smp_processor_id();
|
||||
old = atomic_cmpxchg(&dump_lock, -1, cpu);
|
||||
if (old == -1) {
|
||||
@@ -43,6 +43,7 @@ retry:
|
||||
} else if (old == cpu) {
|
||||
was_locked = 1;
|
||||
} else {
|
||||
local_irq_restore(flags);
|
||||
cpu_relax();
|
||||
goto retry;
|
||||
}
|
||||
@@ -52,7 +53,7 @@ retry:
|
||||
if (!was_locked)
|
||||
atomic_set(&dump_lock, -1);
|
||||
|
||||
preempt_enable();
|
||||
local_irq_restore(flags);
|
||||
}
|
||||
#else
|
||||
asmlinkage __visible void dump_stack(void)
|
||||
|
@@ -282,9 +282,9 @@ void klist_iter_init_node(struct klist *k, struct klist_iter *i,
|
||||
struct klist_node *n)
|
||||
{
|
||||
i->i_klist = k;
|
||||
i->i_cur = n;
|
||||
if (n)
|
||||
kref_get(&n->n_ref);
|
||||
i->i_cur = NULL;
|
||||
if (n && kref_get_unless_zero(&n->n_ref))
|
||||
i->i_cur = n;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(klist_iter_init_node);
|
||||
|
||||
|
@@ -1019,9 +1019,13 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
|
||||
return 0;
|
||||
|
||||
radix_tree_for_each_slot(slot, root, &iter, first_index) {
|
||||
results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot));
|
||||
results[ret] = rcu_dereference_raw(*slot);
|
||||
if (!results[ret])
|
||||
continue;
|
||||
if (radix_tree_is_indirect_ptr(results[ret])) {
|
||||
slot = radix_tree_iter_retry(&iter);
|
||||
continue;
|
||||
}
|
||||
if (++ret == max_items)
|
||||
break;
|
||||
}
|
||||
@@ -1098,9 +1102,13 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
|
||||
return 0;
|
||||
|
||||
radix_tree_for_each_tagged(slot, root, &iter, first_index, tag) {
|
||||
results[ret] = indirect_to_ptr(rcu_dereference_raw(*slot));
|
||||
results[ret] = rcu_dereference_raw(*slot);
|
||||
if (!results[ret])
|
||||
continue;
|
||||
if (radix_tree_is_indirect_ptr(results[ret])) {
|
||||
slot = radix_tree_iter_retry(&iter);
|
||||
continue;
|
||||
}
|
||||
if (++ret == max_items)
|
||||
break;
|
||||
}
|
||||
|
@@ -598,9 +598,9 @@ EXPORT_SYMBOL(sg_miter_next);
|
||||
*
|
||||
* Description:
|
||||
* Stops mapping iterator @miter. @miter should have been started
|
||||
* started using sg_miter_start(). A stopped iteration can be
|
||||
* resumed by calling sg_miter_next() on it. This is useful when
|
||||
* resources (kmap) need to be released during iteration.
|
||||
* using sg_miter_start(). A stopped iteration can be resumed by
|
||||
* calling sg_miter_next() on it. This is useful when resources (kmap)
|
||||
* need to be released during iteration.
|
||||
*
|
||||
* Context:
|
||||
* Preemption disabled if the SG_MITER_ATOMIC is set. Don't care
|
||||
|
@@ -327,36 +327,67 @@ out:
|
||||
}
|
||||
|
||||
#define string_get_size_maxbuf 16
|
||||
#define test_string_get_size_one(size, blk_size, units, exp_result) \
|
||||
#define test_string_get_size_one(size, blk_size, exp_result10, exp_result2) \
|
||||
do { \
|
||||
BUILD_BUG_ON(sizeof(exp_result) >= string_get_size_maxbuf); \
|
||||
__test_string_get_size((size), (blk_size), (units), \
|
||||
(exp_result)); \
|
||||
BUILD_BUG_ON(sizeof(exp_result10) >= string_get_size_maxbuf); \
|
||||
BUILD_BUG_ON(sizeof(exp_result2) >= string_get_size_maxbuf); \
|
||||
__test_string_get_size((size), (blk_size), (exp_result10), \
|
||||
(exp_result2)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
static __init void __test_string_get_size(const u64 size, const u64 blk_size,
|
||||
const enum string_size_units units,
|
||||
const char *exp_result)
|
||||
static __init void test_string_get_size_check(const char *units,
|
||||
const char *exp,
|
||||
char *res,
|
||||
const u64 size,
|
||||
const u64 blk_size)
|
||||
{
|
||||
char buf[string_get_size_maxbuf];
|
||||
|
||||
string_get_size(size, blk_size, units, buf, sizeof(buf));
|
||||
if (!memcmp(buf, exp_result, strlen(exp_result) + 1))
|
||||
if (!memcmp(res, exp, strlen(exp) + 1))
|
||||
return;
|
||||
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
pr_warn("Test 'test_string_get_size_one' failed!\n");
|
||||
pr_warn("string_get_size(size = %llu, blk_size = %llu, units = %d\n",
|
||||
res[string_get_size_maxbuf - 1] = '\0';
|
||||
|
||||
pr_warn("Test 'test_string_get_size' failed!\n");
|
||||
pr_warn("string_get_size(size = %llu, blk_size = %llu, units = %s)\n",
|
||||
size, blk_size, units);
|
||||
pr_warn("expected: '%s', got '%s'\n", exp_result, buf);
|
||||
pr_warn("expected: '%s', got '%s'\n", exp, res);
|
||||
}
|
||||
|
||||
static __init void __test_string_get_size(const u64 size, const u64 blk_size,
|
||||
const char *exp_result10,
|
||||
const char *exp_result2)
|
||||
{
|
||||
char buf10[string_get_size_maxbuf];
|
||||
char buf2[string_get_size_maxbuf];
|
||||
|
||||
string_get_size(size, blk_size, STRING_UNITS_10, buf10, sizeof(buf10));
|
||||
string_get_size(size, blk_size, STRING_UNITS_2, buf2, sizeof(buf2));
|
||||
|
||||
test_string_get_size_check("STRING_UNITS_10", exp_result10, buf10,
|
||||
size, blk_size);
|
||||
|
||||
test_string_get_size_check("STRING_UNITS_2", exp_result2, buf2,
|
||||
size, blk_size);
|
||||
}
|
||||
|
||||
static __init void test_string_get_size(void)
|
||||
{
|
||||
test_string_get_size_one(16384, 512, STRING_UNITS_2, "8.00 MiB");
|
||||
test_string_get_size_one(8192, 4096, STRING_UNITS_10, "32.7 MB");
|
||||
test_string_get_size_one(1, 512, STRING_UNITS_10, "512 B");
|
||||
/* small values */
|
||||
test_string_get_size_one(0, 512, "0 B", "0 B");
|
||||
test_string_get_size_one(1, 512, "512 B", "512 B");
|
||||
test_string_get_size_one(1100, 1, "1.10 kB", "1.07 KiB");
|
||||
|
||||
/* normal values */
|
||||
test_string_get_size_one(16384, 512, "8.39 MB", "8.00 MiB");
|
||||
test_string_get_size_one(500118192, 512, "256 GB", "238 GiB");
|
||||
test_string_get_size_one(8192, 4096, "33.6 MB", "32.0 MiB");
|
||||
|
||||
/* weird block sizes */
|
||||
test_string_get_size_one(3000, 1900, "5.70 MB", "5.44 MiB");
|
||||
|
||||
/* huge values */
|
||||
test_string_get_size_one(U64_MAX, 4096, "75.6 ZB", "64.0 ZiB");
|
||||
test_string_get_size_one(4096, U64_MAX, "75.6 ZB", "64.0 ZiB");
|
||||
}
|
||||
|
||||
static int __init test_string_helpers_init(void)
|
||||
|
@@ -1590,22 +1590,23 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
|
||||
return buf;
|
||||
}
|
||||
case 'K':
|
||||
/*
|
||||
* %pK cannot be used in IRQ context because its test
|
||||
* for CAP_SYSLOG would be meaningless.
|
||||
*/
|
||||
if (kptr_restrict && (in_irq() || in_serving_softirq() ||
|
||||
in_nmi())) {
|
||||
if (spec.field_width == -1)
|
||||
spec.field_width = default_width;
|
||||
return string(buf, end, "pK-error", spec);
|
||||
}
|
||||
|
||||
switch (kptr_restrict) {
|
||||
case 0:
|
||||
/* Always print %pK values */
|
||||
break;
|
||||
case 1: {
|
||||
const struct cred *cred;
|
||||
|
||||
/*
|
||||
* kptr_restrict==1 cannot be used in IRQ context
|
||||
* because its test for CAP_SYSLOG would be meaningless.
|
||||
*/
|
||||
if (in_irq() || in_serving_softirq() || in_nmi()) {
|
||||
if (spec.field_width == -1)
|
||||
spec.field_width = default_width;
|
||||
return string(buf, end, "pK-error", spec);
|
||||
}
|
||||
|
||||
/*
|
||||
* Only print the real pointer value if the current
|
||||
* process has CAP_SYSLOG and is running with the
|
||||
@@ -1615,8 +1616,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
|
||||
* leak pointer values if a binary opens a file using
|
||||
* %pK and then elevates privileges before reading it.
|
||||
*/
|
||||
const struct cred *cred = current_cred();
|
||||
|
||||
cred = current_cred();
|
||||
if (!has_capability_noaudit(current, CAP_SYSLOG) ||
|
||||
!uid_eq(cred->euid, cred->uid) ||
|
||||
!gid_eq(cred->egid, cred->gid))
|
||||
|
Reference in New Issue
Block a user