Merge tag 'printk-for-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/printk...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 23 Mar 2022 17:54:27 +0000 (10:54 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 23 Mar 2022 17:54:27 +0000 (10:54 -0700)
Pull printk updates from Petr Mladek:

 - Make %pK behave the same as %p for kptr_restrict == 0 also with
   no_hash_pointers parameter

 - Ignore the default console in the device tree also when console=null
   or console="" is used on the command line

 - Document console=null and console="" behavior

 - Prevent a deadlock and a livelock caused by console_lock in panic()

 - Make console_lock available for panicking CPU

 - Fast query for the next to-be-used sequence number

 - Use the expected return values in printk.devkmsg __setup handler

 - Use the correct atomic operations in wake_up_klogd() irq_work handler

 - Avoid possible unaligned access when handling %4cc printing format

* tag 'printk-for-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux:
  printk: fix return value of printk.devkmsg __setup handler
  vsprintf: Fix %pK with kptr_restrict == 0
  printk: make suppress_panic_printk static
  printk: Set console_set_on_cmdline=1 when __add_preferred_console() is called with user_specified == true
  Docs: printk: add 'console=null|""' to admin/kernel-parameters
  printk: use atomic updates for klogd work
  printk: Drop console_sem during panic
  printk: Avoid livelock with heavy printk during panic
  printk: disable optimistic spin during panic
  printk: Add panic_in_progress helper
  vsprintf: Move space out of string literals in fourcc_string()
  vsprintf: Fix potential unaligned access
  printk: ringbuffer: Improve prb_next_seq() performance

1  2 
Documentation/admin-guide/kernel-parameters.txt
kernel/printk/printk.c
lib/vsprintf.c

index 09cdee9e3bad90e0e80a614b02875242973a277d,86e2b586c1716bc4f9febdea7259d30295c398fd..1a9f89a835b3b1b37ac5dc7e077ad09bc6b09afe
        clocksource.max_cswd_read_retries= [KNL]
                        Number of clocksource_watchdog() retries due to
                        external delays before the clock will be marked
 -                      unstable.  Defaults to three retries, that is,
 -                      four attempts to read the clock under test.
 +                      unstable.  Defaults to two retries, that is,
 +                      three attempts to read the clock under test.
  
        clocksource.verify_n_cpus= [KNL]
                        Limit the number of CPUs checked for clocksources
                hvc<n>  Use the hypervisor console device <n>. This is for
                        both Xen and PowerPC hypervisors.
  
+               { null | "" }
+                       Use to disable console output, i.e., to have kernel
+                       console messages discarded.
+                       This must be the only console= parameter used on the
+                       kernel command line.
                If the device connected to the port is not a TTY but a braille
                device, prepend "brl," before the device type, for instance
                        console=brl,ttyS0
                        dump out devices still on the deferred probe list after
                        retrying.
  
 +      dell_smm_hwmon.ignore_dmi=
 +                      [HW] Continue probing hardware even if DMI data
 +                      indicates that the driver is running on unsupported
 +                      hardware.
 +
 +      dell_smm_hwmon.force=
 +                      [HW] Activate driver even if SMM BIOS signature does
 +                      not match list of supported models and enable otherwise
 +                      blacklisted features.
 +
 +      dell_smm_hwmon.power_status=
 +                      [HW] Report power status in /proc/i8k
 +                      (disabled by default).
 +
 +      dell_smm_hwmon.restricted=
 +                      [HW] Allow controlling fans only if SYS_ADMIN
 +                      capability is set.
 +
 +      dell_smm_hwmon.fan_mult=
 +                      [HW] Factor to multiply fan speed with.
 +
 +      dell_smm_hwmon.fan_max=
 +                      [HW] Maximum configurable fan speed.
 +
        dfltcc=         [HW,S390]
                        Format: { on | off | def_only | inf_only | always }
                        on:       s390 zlib hardware support for compression on
                        [KNL] Reguires CONFIG_HUGETLB_PAGE_FREE_VMEMMAP
                        enabled.
                        Allows heavy hugetlb users to free up some more
 -                      memory (6 * PAGE_SIZE for each 2MB hugetlb page).
 +                      memory (7 * PAGE_SIZE for each 2MB hugetlb page).
                        Format: { on | off (default) }
  
                        on:  enable the feature
  
        i810=           [HW,DRM]
  
 -      i8k.ignore_dmi  [HW] Continue probing hardware even if DMI data
 -                      indicates that the driver is running on unsupported
 -                      hardware.
 -      i8k.force       [HW] Activate i8k driver even if SMM BIOS signature
 -                      does not match list of supported models.
 -      i8k.power_status
 -                      [HW] Report power status in /proc/i8k
 -                      (disabled by default)
 -      i8k.restricted  [HW] Allow controlling fans only if SYS_ADMIN
 -                      capability is set.
 -
        i915.invert_brightness=
                        [DRM] Invert the sense of the variable that is used to
                        set the brightness of the panel backlight. Normally a
  
                        For details see: Documentation/admin-guide/hw-vuln/mds.rst
  
 +      mem=nn[KMG]     [HEXAGON] Set the memory size.
 +                      Must be specified, otherwise memory size will be 0.
 +
        mem=nn[KMG]     [KNL,BOOT] Force usage of a specific amount of memory
                        Amount of memory to be used in cases as follows:
  
                        2 when the kernel is not able to see the whole system memory;
                        3 memory that lies after 'mem=' boundary is excluded from
                         the hypervisor, then assigned to KVM guests.
 +                      4 to limit the memory available for kdump kernel.
 +
 +                      [ARC,MICROBLAZE] - the limit applies only to low memory,
 +                      high memory is not affected.
 +
 +                      [ARM64] - only limits memory covered by the linear
 +                      mapping. The NOMAP regions are not affected.
  
                        [X86] Work as limiting max address. Use together
                        with memmap= to avoid physical address space collisions.
                        in above case 3, memory may need be hot added after boot
                        if system memory of hypervisor is not sufficient.
  
 +      mem=nn[KMG]@ss[KMG]
 +                      [ARM,MIPS] - override the memory layout reported by
 +                      firmware.
 +                      Define a memory region of size nn[KMG] starting at
 +                      ss[KMG].
 +                      Multiple different regions can be specified with
 +                      multiple mem= parameters on the command line.
 +
        mem=nopentium   [BUGS=X86-32] Disable usage of 4MB pages for kernel
                        memory.
  
                        Disable SMAP (Supervisor Mode Access Prevention)
                        even if it is supported by processor.
  
 -      nosmep          [X86,PPC]
 +      nosmep          [X86,PPC64s]
                        Disable SMEP (Supervisor Mode Execution Prevention)
                        even if it is supported by processor.
  
                        difficult since unequal pointers can no longer be
                        compared.  However, if this command-line option is
                        specified, then all normal pointers will have their true
-                       value printed.  Pointers printed via %pK may still be
-                       hashed.  This option should only be specified when
+                       value printed. This option should only be specified when
                        debugging the kernel.  Please do not use on production
                        kernels.
  
                        Override pmtimer IOPort with a hex value.
                        e.g. pmtmr=0x508
  
 +      pmu_override=   [PPC] Override the PMU.
 +                      This option takes over the PMU facility, so it is no
 +                      longer usable by perf. Setting this option starts the
 +                      PMU counters by setting MMCR0 to 0 (the FC bit is
 +                      cleared). If a number is given, then MMCR1 is set to
 +                      that number, otherwise (e.g., 'pmu_override=on'), MMCR1
 +                      remains 0.
 +
        pm_debug_messages       [SUSPEND,KNL]
                        Enable suspend/resume debug messages during boot up.
  
                                Disable the Correctable Errors Collector,
                                see CONFIG_RAS_CEC help text.
  
 -      rcu_nocbs=      [KNL]
 -                      The argument is a cpu list, as described above.
 -
 -                      In kernels built with CONFIG_RCU_NOCB_CPU=y, set
 -                      the specified list of CPUs to be no-callback CPUs.
 -                      Invocation of these CPUs' RCU callbacks will be
 -                      offloaded to "rcuox/N" kthreads created for that
 -                      purpose, where "x" is "p" for RCU-preempt, and
 -                      "s" for RCU-sched, and "N" is the CPU number.
 -                      This reduces OS jitter on the offloaded CPUs,
 -                      which can be useful for HPC and real-time
 -                      workloads.  It can also improve energy efficiency
 -                      for asymmetric multiprocessors.
 +      rcu_nocbs[=cpu-list]
 +                      [KNL] The optional argument is a cpu list,
 +                      as described above.
 +
 +                      In kernels built with CONFIG_RCU_NOCB_CPU=y,
 +                      enable the no-callback CPU mode, which prevents
 +                      such CPUs' callbacks from being invoked in
 +                      softirq context.  Invocation of such CPUs' RCU
 +                      callbacks will instead be offloaded to "rcuox/N"
 +                      kthreads created for that purpose, where "x" is
 +                      "p" for RCU-preempt, "s" for RCU-sched, and "g"
 +                      for the kthreads that mediate grace periods; and
 +                      "N" is the CPU number. This reduces OS jitter on
 +                      the offloaded CPUs, which can be useful for HPC
 +                      and real-time workloads.  It can also improve
 +                      energy efficiency for asymmetric multiprocessors.
 +
 +                      If a cpulist is passed as an argument, the specified
 +                      list of CPUs is set to no-callback mode from boot.
 +
 +                      Otherwise, if the '=' sign and the cpulist
 +                      arguments are omitted, no CPU will be set to
 +                      no-callback mode from boot but the mode may be
 +                      toggled at runtime via cpusets.
  
        rcu_nocb_poll   [KNL]
                        Rather than requiring that offloaded CPUs
                        (the least-favored priority).  Otherwise, when
                        RCU_BOOST is not set, valid values are 0-99 and
                        the default is zero (non-realtime operation).
 +                      When RCU_NOCB_CPU is set, also adjust the
 +                      priority of NOCB callback kthreads.
  
        rcutree.rcu_nocb_gp_stride= [KNL]
                        Set the number of NOCB callback kthreads in
                        on rcutree.qhimark at boot time and to zero to
                        disable more aggressive help enlistment.
  
 -      rcutree.rcu_idle_gp_delay= [KNL]
 -                      Set wakeup interval for idle CPUs that have
 -                      RCU callbacks (RCU_FAST_NO_HZ=y).
 -
        rcutree.rcu_kick_kthreads= [KNL]
                        Cause the grace-period kthread to get an extra
                        wake_up() if it sleeps three times longer than
                        in seconds.
  
        rcutorture.fwd_progress= [KNL]
 -                      Enable RCU grace-period forward-progress testing
 +                      Specifies the number of kthreads to be used
 +                      for  RCU grace-period forward-progress testing
                        for the types of RCU supporting this notion.
 +                      Defaults to 1 kthread, values less than zero or
 +                      greater than the number of CPUs cause the number
 +                      of CPUs to be used.
  
        rcutorture.fwd_progress_div= [KNL]
                        Specify the fraction of a CPU-stall-warning
                        period to instead use normal non-expedited
                        grace-period processing.
  
 +      rcupdate.rcu_task_collapse_lim= [KNL]
 +                      Set the maximum number of callbacks present
 +                      at the beginning of a grace period that allows
 +                      the RCU Tasks flavors to collapse back to using
 +                      a single callback queue.  This switching only
 +                      occurs when rcupdate.rcu_task_enqueue_lim is
 +                      set to the default value of -1.
 +
 +      rcupdate.rcu_task_contend_lim= [KNL]
 +                      Set the minimum number of callback-queuing-time
 +                      lock-contention events per jiffy required to
 +                      cause the RCU Tasks flavors to switch to per-CPU
 +                      callback queuing.  This switching only occurs
 +                      when rcupdate.rcu_task_enqueue_lim is set to
 +                      the default value of -1.
 +
 +      rcupdate.rcu_task_enqueue_lim= [KNL]
 +                      Set the number of callback queues to use for the
 +                      RCU Tasks family of RCU flavors.  The default
 +                      of -1 allows this to be automatically (and
 +                      dynamically) adjusted.  This parameter is intended
 +                      for use in testing.
 +
        rcupdate.rcu_task_ipi_delay= [KNL]
                        Set time in jiffies during which RCU tasks will
                        avoid sending IPIs, starting with the beginning
                        Specific mitigations can also be selected manually:
  
                        retpoline         - replace indirect branches
 -                      retpoline,generic - google's original retpoline
 -                      retpoline,amd     - AMD-specific minimal thunk
 +                      retpoline,generic - Retpolines
 +                      retpoline,lfence  - LFENCE; indirect branch
 +                      retpoline,amd     - alias for retpoline,lfence
 +                      eibrs             - enhanced IBRS
 +                      eibrs,retpoline   - enhanced IBRS + Retpolines
 +                      eibrs,lfence      - enhanced IBRS + LFENCE
  
                        Not specifying this option is equivalent to
                        spectre_v2=auto.
                                  controller on both pseries and powernv
                                  platforms. Only useful on POWER9 and above.
  
 +      xive.store-eoi=off      [PPC]
 +                      By default on POWER10 and above, the kernel will use
 +                      stores for EOI handling when the XIVE interrupt mode
 +                      is active. This option allows the XIVE driver to use
 +                      loads instead, as on POWER9.
 +
        xhci-hcd.quirks         [USB,KNL]
                        A hex value specifying bitmask with supplemental xhci
                        host controller quirks. Meaning of each bit can be
diff --combined kernel/printk/printk.c
index 82abfaf3c2aadc17c1d5dd6896c351e999fa17fd,49aa47e876db53302d7c6457ab7f9de3249b40db..da03c15ecc898076242623123e30e9c2d6e26c5d
@@@ -93,6 -93,12 +93,12 @@@ EXPORT_SYMBOL_GPL(console_drivers)
   */
  int __read_mostly suppress_printk;
  
+ /*
+  * During panic, heavy printk by other CPUs can delay the
+  * panic and risk deadlock on console resources.
+  */
+ static int __read_mostly suppress_panic_printk;
  #ifdef CONFIG_LOCKDEP
  static struct lockdep_map console_lock_dep_map = {
        .name = "console_lock"
@@@ -146,8 -152,10 +152,10 @@@ static int __control_devkmsg(char *str
  
  static int __init control_devkmsg(char *str)
  {
-       if (__control_devkmsg(str) < 0)
+       if (__control_devkmsg(str) < 0) {
+               pr_warn("printk.devkmsg: bad option string '%s'\n", str);
                return 1;
+       }
  
        /*
         * Set sysctl string accordingly:
         */
        devkmsg_log |= DEVKMSG_LOG_MASK_LOCK;
  
-       return 0;
+       return 1;
  }
  __setup("printk.devkmsg=", control_devkmsg);
  
  char devkmsg_log_str[DEVKMSG_STR_MAX_SIZE] = "ratelimit";
 -
 +#if defined(CONFIG_PRINTK) && defined(CONFIG_SYSCTL)
  int devkmsg_sysctl_set_loglvl(struct ctl_table *table, int write,
                              void *buffer, size_t *lenp, loff_t *ppos)
  {
  
        return 0;
  }
 +#endif /* CONFIG_PRINTK && CONFIG_SYSCTL */
  
  /* Number of registered extended console drivers. */
  static int nr_ext_console_drivers;
@@@ -257,6 -264,11 +265,11 @@@ static void __up_console_sem(unsigned l
  }
  #define up_console_sem() __up_console_sem(_RET_IP_)
  
+ static bool panic_in_progress(void)
+ {
+       return unlikely(atomic_read(&panic_cpu) != PANIC_CPU_INVALID);
+ }
  /*
   * This is used for debugging the mess that is the VT code by
   * keeping track if we have the console semaphore held. It's
@@@ -1843,6 -1855,16 +1856,16 @@@ static int console_trylock_spinning(voi
        if (console_trylock())
                return 1;
  
+       /*
+        * It's unsafe to spin once a panic has begun. If we are the
+        * panic CPU, we may have already halted the owner of the
+        * console_sem. If we are not the panic CPU, then we should
+        * avoid taking console_sem, so the panic CPU has a better
+        * chance of cleanly acquiring it later.
+        */
+       if (panic_in_progress())
+               return 0;
        printk_safe_enter_irqsave(flags);
  
        raw_spin_lock(&console_owner_lock);
@@@ -2218,6 -2240,10 +2241,10 @@@ asmlinkage int vprintk_emit(int facilit
        if (unlikely(suppress_printk))
                return 0;
  
+       if (unlikely(suppress_panic_printk) &&
+           atomic_read(&panic_cpu) != raw_smp_processor_id())
+               return 0;
        if (level == LOGLEVEL_SCHED) {
                level = LOGLEVEL_DEFAULT;
                in_sched = true;
@@@ -2324,6 -2350,20 +2351,20 @@@ asmlinkage __visible void early_printk(
  }
  #endif
  
+ static void set_user_specified(struct console_cmdline *c, bool user_specified)
+ {
+       if (!user_specified)
+               return;
+       /*
+        * @c console was defined by the user on the command line.
+        * Do not clear when added twice also by SPCR or the device tree.
+        */
+       c->user_specified = true;
+       /* At least one console defined by the user on the command line. */
+       console_set_on_cmdline = 1;
+ }
  static int __add_preferred_console(char *name, int idx, char *options,
                                   char *brl_options, bool user_specified)
  {
                if (strcmp(c->name, name) == 0 && c->index == idx) {
                        if (!brl_options)
                                preferred_console = i;
-                       if (user_specified)
-                               c->user_specified = true;
+                       set_user_specified(c, user_specified);
                        return 0;
                }
        }
                preferred_console = i;
        strlcpy(c->name, name, sizeof(c->name));
        c->options = options;
-       c->user_specified = user_specified;
+       set_user_specified(c, user_specified);
        braille_set_options(c, brl_options);
  
        c->index = idx;
@@@ -2417,7 -2456,6 +2457,6 @@@ static int __init console_setup(char *s
        *s = 0;
  
        __add_preferred_console(buf, idx, options, brl_options, true);
-       console_set_on_cmdline = 1;
        return 1;
  }
  __setup("console=", console_setup);
@@@ -2573,6 -2611,25 +2612,25 @@@ static int have_callable_console(void
        return 0;
  }
  
+ /*
+  * Return true when this CPU should unlock console_sem without pushing all
+  * messages to the console. This reduces the chance that the console is
+  * locked when the panic CPU tries to use it.
+  */
+ static bool abandon_console_lock_in_panic(void)
+ {
+       if (!panic_in_progress())
+               return false;
+       /*
+        * We can use raw_smp_processor_id() here because it is impossible for
+        * the task to be migrated to the panic_cpu, or away from it. If
+        * panic_cpu has already been set, and we're not currently executing on
+        * that CPU, then we never will be.
+        */
+       return atomic_read(&panic_cpu) != raw_smp_processor_id();
+ }
  /*
   * Can we actually use the console at this time on this cpu?
   *
@@@ -2603,6 -2660,7 +2661,7 @@@ void console_unlock(void
  {
        static char ext_text[CONSOLE_EXT_LOG_MAX];
        static char text[CONSOLE_LOG_MAX];
+       static int panic_console_dropped;
        unsigned long flags;
        bool do_cond_resched, retry;
        struct printk_info info;
@@@ -2657,6 -2715,10 +2716,10 @@@ skip
                if (console_seq != r.info->seq) {
                        console_dropped += r.info->seq - console_seq;
                        console_seq = r.info->seq;
+                       if (panic_in_progress() && panic_console_dropped++ > 10) {
+                               suppress_panic_printk = 1;
+                               pr_warn_once("Too many dropped messages. Suppress messages on non-panic CPUs to prevent livelock.\n");
+                       }
                }
  
                if (suppress_message_printing(r.info->level)) {
                if (handover)
                        return;
  
+               /* Allow panic_cpu to take over the consoles safely */
+               if (abandon_console_lock_in_panic())
+                       break;
                if (do_cond_resched)
                        cond_resched();
        }
         * flush, no worries.
         */
        retry = prb_read_valid(prb, next_seq, NULL);
-       if (retry && console_trylock())
+       if (retry && !abandon_console_lock_in_panic() && console_trylock())
                goto again;
  }
  EXPORT_SYMBOL(console_unlock);
@@@ -3212,7 -3278,6 +3279,7 @@@ static int __init printk_late_init(void
        ret = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN, "printk:online",
                                        console_cpu_notify, NULL);
        WARN_ON(ret < 0);
 +      printk_sysctl_init();
        return 0;
  }
  late_initcall(printk_late_init);
@@@ -3228,7 -3293,7 +3295,7 @@@ static DEFINE_PER_CPU(int, printk_pendi
  
  static void wake_up_klogd_work_func(struct irq_work *irq_work)
  {
-       int pending = __this_cpu_xchg(printk_pending, 0);
+       int pending = this_cpu_xchg(printk_pending, 0);
  
        if (pending & PRINTK_PENDING_OUTPUT) {
                /* If trylock fails, someone else is doing the printing */
@@@ -3262,7 -3327,7 +3329,7 @@@ void defer_console_output(void
                return;
  
        preempt_disable();
-       __this_cpu_or(printk_pending, PRINTK_PENDING_OUTPUT);
+       this_cpu_or(printk_pending, PRINTK_PENDING_OUTPUT);
        irq_work_queue(this_cpu_ptr(&wake_up_klogd_work));
        preempt_enable();
  }
diff --combined lib/vsprintf.c
index 36574a806a8124cb65569d749e456957446ed8bc,51495c1aceb895275893383f29f21635ac5e8148..53fe73a48adfe032e7ae96f7cddd7769cce1ff8e
  
  #include <asm/page.h>         /* for PAGE_SIZE */
  #include <asm/byteorder.h>    /* cpu_to_le16 */
+ #include <asm/unaligned.h>
  
  #include <linux/string_helpers.h>
  #include "kstrtox.h"
  
+ /* Disable pointer hashing if requested */
+ bool no_hash_pointers __ro_after_init;
+ EXPORT_SYMBOL_GPL(no_hash_pointers);
  static noinline unsigned long long simple_strntoull(const char *startp, size_t max_chars, char **endp, unsigned int base)
  {
        const char *cp;
@@@ -757,16 -762,14 +762,16 @@@ static void enable_ptr_key_workfn(struc
  
  static DECLARE_WORK(enable_ptr_key_work, enable_ptr_key_workfn);
  
 -static void fill_random_ptr_key(struct random_ready_callback *unused)
 +static int fill_random_ptr_key(struct notifier_block *nb,
 +                             unsigned long action, void *data)
  {
        /* This may be in an interrupt handler. */
        queue_work(system_unbound_wq, &enable_ptr_key_work);
 +      return 0;
  }
  
 -static struct random_ready_callback random_ready = {
 -      .func = fill_random_ptr_key
 +static struct notifier_block random_ready = {
 +      .notifier_call = fill_random_ptr_key
  };
  
  static int __init initialize_ptr_random(void)
                return 0;
        }
  
 -      ret = add_random_ready_callback(&random_ready);
 +      ret = register_random_ready_notifier(&random_ready);
        if (!ret) {
                return 0;
        } else if (ret == -EALREADY) {
@@@ -850,6 -853,19 +855,19 @@@ static char *ptr_to_id(char *buf, char 
        return pointer_string(buf, end, (const void *)hashval, spec);
  }
  
+ static char *default_pointer(char *buf, char *end, const void *ptr,
+                            struct printf_spec spec)
+ {
+       /*
+        * default is to _not_ leak addresses, so hash before printing,
+        * unless no_hash_pointers is specified on the command line.
+        */
+       if (unlikely(no_hash_pointers))
+               return pointer_string(buf, end, ptr, spec);
+       return ptr_to_id(buf, end, ptr, spec);
+ }
  int kptr_restrict __read_mostly;
  
  static noinline_for_stack
@@@ -859,7 -875,7 +877,7 @@@ char *restricted_pointer(char *buf, cha
        switch (kptr_restrict) {
        case 0:
                /* Handle as %p, hash and do _not_ leak addresses. */
-               return ptr_to_id(buf, end, ptr, spec);
+               return default_pointer(buf, end, ptr, spec);
        case 1: {
                const struct cred *cred;
  
@@@ -1243,13 -1259,20 +1261,13 @@@ char *bitmap_list_string(char *buf, cha
                         struct printf_spec spec, const char *fmt)
  {
        int nr_bits = max_t(int, spec.field_width, 0);
 -      /* current bit is 'cur', most recently seen range is [rbot, rtop] */
 -      int cur, rbot, rtop;
        bool first = true;
 +      int rbot, rtop;
  
        if (check_pointer(&buf, end, bitmap, spec))
                return buf;
  
 -      rbot = cur = find_first_bit(bitmap, nr_bits);
 -      while (cur < nr_bits) {
 -              rtop = cur;
 -              cur = find_next_bit(bitmap, nr_bits, cur + 1);
 -              if (cur < nr_bits && cur <= rtop + 1)
 -                      continue;
 -
 +      for_each_set_bitrange(rbot, rtop, bitmap, nr_bits) {
                if (!first) {
                        if (buf < end)
                                *buf = ',';
                first = false;
  
                buf = number(buf, end, rbot, default_dec_spec);
 -              if (rbot < rtop) {
 -                      if (buf < end)
 -                              *buf = '-';
 -                      buf++;
 -
 -                      buf = number(buf, end, rtop, default_dec_spec);
 -              }
 +              if (rtop == rbot + 1)
 +                      continue;
  
 -              rbot = cur;
 +              if (buf < end)
 +                      *buf = '-';
 +              buf = number(++buf, end, rtop - 1, default_dec_spec);
        }
        return buf;
  }
@@@ -1763,7 -1789,7 +1781,7 @@@ char *fourcc_string(char *buf, char *en
        char output[sizeof("0123 little-endian (0x01234567)")];
        char *p = output;
        unsigned int i;
-       u32 val;
+       u32 orig, val;
  
        if (fmt[1] != 'c' || fmt[2] != 'c')
                return error_string(buf, end, "(%p4?)", spec);
        if (check_pointer(&buf, end, fourcc, spec))
                return buf;
  
-       val = *fourcc & ~BIT(31);
+       orig = get_unaligned(fourcc);
+       val = orig & ~BIT(31);
  
-       for (i = 0; i < sizeof(*fourcc); i++) {
+       for (i = 0; i < sizeof(u32); i++) {
                unsigned char c = val >> (i * 8);
  
                /* Print non-control ASCII characters as-is, dot otherwise */
                *p++ = isascii(c) && isprint(c) ? c : '.';
        }
  
-       strcpy(p, *fourcc & BIT(31) ? " big-endian" : " little-endian");
+       *p++ = ' ';
+       strcpy(p, orig & BIT(31) ? "big-endian" : "little-endian");
        p += strlen(p);
  
        *p++ = ' ';
        *p++ = '(';
-       p = special_hex_number(p, output + sizeof(output) - 2, *fourcc, sizeof(u32));
+       p = special_hex_number(p, output + sizeof(output) - 2, orig, sizeof(u32));
        *p++ = ')';
        *p = '\0';
  
@@@ -2225,10 -2253,6 +2245,6 @@@ char *fwnode_string(char *buf, char *en
        return widen_string(buf, buf - buf_start, end, spec);
  }
  
- /* Disable pointer hashing if requested */
- bool no_hash_pointers __ro_after_init;
- EXPORT_SYMBOL_GPL(no_hash_pointers);
  int __init no_hash_pointers_enable(char *str)
  {
        if (no_hash_pointers)
@@@ -2457,7 -2481,7 +2473,7 @@@ char *pointer(const char *fmt, char *bu
        case 'e':
                /* %pe with a non-ERR_PTR gets treated as plain %p */
                if (!IS_ERR(ptr))
-                       break;
+                       return default_pointer(buf, end, ptr, spec);
                return err_ptr(buf, end, ptr, spec);
        case 'u':
        case 'k':
                default:
                        return error_string(buf, end, "(einval)", spec);
                }
+       default:
+               return default_pointer(buf, end, ptr, spec);
        }
-       /*
-        * default is to _not_ leak addresses, so hash before printing,
-        * unless no_hash_pointers is specified on the command line.
-        */
-       if (unlikely(no_hash_pointers))
-               return pointer_string(buf, end, ptr, spec);
-       else
-               return ptr_to_id(buf, end, ptr, spec);
  }
  
  /*