mirror of
https://github.com/torvalds/linux.git
synced 2026-09-11 20:13:02 +02:00
printk changes for 7.3
-----BEGIN PGP SIGNATURE----- iQJPBAABCAA5FiEESH4wyp42V4tXvYsjUqAMR0iAlPIFAmqFYyEbFIAAAAAABAAO bWFudTIsMi41KzEuMTIsMiwyAAoJEFKgDEdIgJTyAlwP+gL59ZVbiHyzTRlVMetf 6wYxjnM4B0Efe/BC/526sVZ0ZMvCaT8oNgRCUDYWEBmB1NWmxieQ2YEy5yg9N/3v nDgUenq7gdVLPzv+n3Xrb2ZqzsTssnP6iD/hi4S2uD2/1Bphu0f13K2yLHcgfsgR EKqj2y3bOR4b6Z2YyNWA3wcbbYHccIt1c6pM0t2IJi9L5gbncwfzqdG5qdsG/Ioi Vbd7CVyDTnPArrDNOMe19cvDNxuJcpogNUaAUjtCl2rWqSFFLC9w06LphrjmZ4L2 lpS5C9VVPlsQVxAEoeYQ13v6glL1Iakj2nhKz/uDq5U0hMY5BxRKZNdh96aMEbhZ Yy4DtvmXOQsPBERzjYvMhIK92kTcLW/VgKyt5Ug62IL7r4P0xCtNvdFCRu28PISu pBzzwXcbiSPxVW5iXP/cR6NUsDrty3W3LHlkj1C1SE2RAnJk7XUQRjvpH5hgtzUM A5EDrAO+6MB/fUBzpC1YAwXBiNSZjrBQK9BReybfJA2yYLIrMz2C27+gz5PCAEp8 brozPVQUN9KKL0ZY53mJ+De8x/U9KUtdr8ejVanrOjefVrWt/fzWwbii7UWrve72 u2bfUQ3V4es9raS4BfVD1OiImkrQIBJQNNRX07o/MgWv7yrxAWBHDXQu3X1KkjpV 4pKsBEI4s8/mTNkT/MiE6YAo =Uw8w -----END PGP SIGNATURE----- Merge tag 'printk-for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux Pull printk updates from Petr Mladek: - Prevent a possible out-of-bound access and a use-after-free in rather theoretical situations - Make no_hash_pointers take effect early - Some fixes and clean up of the ratelimit KUnit test * tag 'printk-for-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux: printk: Handle pre-enabled consoles in the top-level register_console() printk: Fix possible console use-after-free lib/tests: test_ratelimit: fix stress test thread lifecycle and leak lib/vsprintf: Make no_hash_pointers take effect early
This commit is contained in:
commit
77ae27fd98
|
|
@ -3264,10 +3264,8 @@ static bool console_flush_one_record(bool do_cond_resched, u64 *next_seq, bool *
|
|||
if (flags & CON_NBCON) {
|
||||
progress = nbcon_legacy_emit_next_record(con, handover, cookie,
|
||||
!do_cond_resched);
|
||||
printk_seq = nbcon_seq_read(con);
|
||||
} else {
|
||||
progress = console_emit_next_record(con, handover, cookie);
|
||||
printk_seq = con->seq;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3277,6 +3275,15 @@ static bool console_flush_one_record(bool do_cond_resched, u64 *next_seq, bool *
|
|||
if (*handover)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* @con can be used here now that it is certain that this
|
||||
* context is still holding the SRCU read lock.
|
||||
*/
|
||||
if (flags & CON_NBCON)
|
||||
printk_seq = nbcon_seq_read(con);
|
||||
else
|
||||
printk_seq = con->seq;
|
||||
|
||||
/* Track the next of the highest seq flushed. */
|
||||
if (printk_seq > *next_seq)
|
||||
*next_seq = printk_seq;
|
||||
|
|
@ -3890,9 +3897,6 @@ static int console_call_setup(struct console *newcon, char *options)
|
|||
* the newly registered console with any of the ones selected
|
||||
* by either the command line or add_preferred_console() and
|
||||
* setup/enable it.
|
||||
*
|
||||
* Care need to be taken with consoles that are statically
|
||||
* enabled such as netconsole
|
||||
*/
|
||||
static int try_enable_preferred_console(struct console *newcon,
|
||||
bool user_specified)
|
||||
|
|
@ -3933,14 +3937,6 @@ static int try_enable_preferred_console(struct console *newcon,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some consoles, such as pstore and netconsole, can be enabled even
|
||||
* without matching. Accept the pre-enabled consoles only when match()
|
||||
* and setup() had a chance to be called.
|
||||
*/
|
||||
if (newcon->flags & CON_ENABLED && c->user_specified == user_specified)
|
||||
return 0;
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
|
|
@ -4123,6 +4119,14 @@ void register_console(struct console *newcon)
|
|||
if (err == -ENOENT)
|
||||
err = try_enable_preferred_console(newcon, false);
|
||||
|
||||
/*
|
||||
* Some consoles, such as pstore and netconsole, can be enabled even
|
||||
* without matching. Accept them at this stage when they had a chance
|
||||
* to match() and call setup().
|
||||
*/
|
||||
if (err == -ENOENT && (newcon->flags & CON_ENABLED))
|
||||
err = 0;
|
||||
|
||||
/* printk() messages are not printed to the Braille console. */
|
||||
if (err || newcon->flags & CON_BRL) {
|
||||
if (newcon->flags & CON_NBCON)
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ static void test_ratelimit_smoke(struct kunit *test)
|
|||
static struct ratelimit_state stressrl = RATELIMIT_STATE_INIT_FLAGS("stressrl", HZ / 10, 3,
|
||||
RATELIMIT_MSG_ON_RELEASE);
|
||||
|
||||
static int doneflag;
|
||||
static const int stress_duration = 2 * HZ;
|
||||
|
||||
struct stress_kthread {
|
||||
|
|
@ -84,9 +83,8 @@ static int test_ratelimit_stress_child(void *arg)
|
|||
struct stress_kthread *sktp = arg;
|
||||
|
||||
set_user_nice(current, MAX_NICE);
|
||||
WARN_ON_ONCE(!sktp->tp);
|
||||
|
||||
while (!READ_ONCE(doneflag)) {
|
||||
while (!kthread_should_stop()) {
|
||||
sktp->nattempts++;
|
||||
if (___ratelimit(&stressrl, __func__))
|
||||
sktp->nunlimited++;
|
||||
|
|
@ -105,26 +103,37 @@ static void test_ratelimit_stress(struct kunit *test)
|
|||
const int n_stress_kthread = cpumask_weight(cpu_online_mask);
|
||||
struct stress_kthread skt = { 0 };
|
||||
struct stress_kthread *sktp = kzalloc_objs(*sktp, n_stress_kthread);
|
||||
int n_started = 0;
|
||||
|
||||
KUNIT_EXPECT_NOT_NULL_MSG(test, sktp, "Memory allocation failure");
|
||||
KUNIT_ASSERT_NOT_NULL_MSG(test, sktp, "Memory allocation failure");
|
||||
for (i = 0; i < n_stress_kthread; i++) {
|
||||
sktp[i].tp = kthread_run(test_ratelimit_stress_child, &sktp[i], "%s/%i",
|
||||
"test_ratelimit_stress_child", i);
|
||||
KUNIT_EXPECT_NOT_NULL_MSG(test, sktp, "kthread creation failure");
|
||||
if (IS_ERR(sktp[i].tp)) {
|
||||
KUNIT_FAIL(test, "kthread_run failed: %ld", PTR_ERR(sktp[i].tp));
|
||||
goto out_stop;
|
||||
}
|
||||
n_started++;
|
||||
pr_alert("Spawned test_ratelimit_stress_child %d\n", i);
|
||||
}
|
||||
schedule_timeout_idle(stress_duration);
|
||||
WRITE_ONCE(doneflag, 1);
|
||||
for (i = 0; i < n_stress_kthread; i++) {
|
||||
|
||||
out_stop:
|
||||
for (i = 0; i < n_started; i++) {
|
||||
kthread_stop(sktp[i].tp);
|
||||
skt.nattempts += sktp[i].nattempts;
|
||||
skt.nunlimited += sktp[i].nunlimited;
|
||||
skt.nlimited += sktp[i].nlimited;
|
||||
skt.nmissed += sktp[i].nmissed;
|
||||
}
|
||||
KUNIT_ASSERT_EQ_MSG(test, skt.nunlimited + skt.nlimited, skt.nattempts,
|
||||
"Outcomes not equal to attempts");
|
||||
KUNIT_ASSERT_EQ_MSG(test, skt.nlimited, skt.nmissed, "Misses not equal to limits");
|
||||
if (n_started == n_stress_kthread) {
|
||||
KUNIT_ASSERT_EQ_MSG(test, skt.nunlimited + skt.nlimited, skt.nattempts,
|
||||
"Outcomes not equal to attempts");
|
||||
KUNIT_ASSERT_EQ_MSG(test, skt.nlimited, skt.nmissed,
|
||||
"Misses not equal to limits");
|
||||
}
|
||||
|
||||
kfree(sktp);
|
||||
}
|
||||
|
||||
static struct kunit_case ratelimit_test_cases[] = {
|
||||
|
|
|
|||
|
|
@ -2360,6 +2360,9 @@ void __init hash_pointers_finalize(bool slub_debug)
|
|||
|
||||
static int __init hash_pointers_mode_parse(char *str)
|
||||
{
|
||||
/* Avoid stale no_hash_pointers state when hash_pointers overrides it */
|
||||
no_hash_pointers = false;
|
||||
|
||||
if (!str) {
|
||||
pr_warn("Hash pointers mode empty; falling back to auto.\n");
|
||||
hash_pointers_mode = HASH_PTR_AUTO;
|
||||
|
|
@ -2369,6 +2372,7 @@ static int __init hash_pointers_mode_parse(char *str)
|
|||
} else if (strcmp(str, "never") == 0) {
|
||||
pr_info("Hash pointers mode set to never.\n");
|
||||
hash_pointers_mode = HASH_PTR_NEVER;
|
||||
no_hash_pointers = true;
|
||||
} else if (strcmp(str, "always") == 0) {
|
||||
pr_info("Hash pointers mode set to always.\n");
|
||||
hash_pointers_mode = HASH_PTR_ALWAYS;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user