|
10 | 10 | #include <linux/export.h> |
11 | 11 | #include <linux/init.h> |
12 | 12 | #include <linux/irqflags.h> |
| 13 | +#include <linux/kdb.h> |
13 | 14 | #include <linux/kthread.h> |
14 | 15 | #include <linux/minmax.h> |
15 | 16 | #include <linux/panic.h> |
@@ -252,13 +253,16 @@ static int nbcon_context_try_acquire_direct(struct nbcon_context *ctxt, |
252 | 253 | * since all non-panic CPUs are stopped during panic(), it |
253 | 254 | * is safer to have them avoid gaining console ownership. |
254 | 255 | * |
255 | | - * If this acquire is a reacquire (and an unsafe takeover |
| 256 | + * One exception is when kdb has locked for printing on this CPU. |
| 257 | + * |
| 258 | + * Second exception is a reacquire (and an unsafe takeover |
256 | 259 | * has not previously occurred) then it is allowed to attempt |
257 | 260 | * a direct acquire in panic. This gives console drivers an |
258 | 261 | * opportunity to perform any necessary cleanup if they were |
259 | 262 | * interrupted by the panic CPU while printing. |
260 | 263 | */ |
261 | 264 | if (panic_on_other_cpu() && |
| 265 | + !kdb_printf_on_this_cpu() && |
262 | 266 | (!is_reacquire || cur->unsafe_takeover)) { |
263 | 267 | return -EPERM; |
264 | 268 | } |
@@ -853,8 +857,8 @@ static bool __nbcon_context_update_unsafe(struct nbcon_context *ctxt, bool unsaf |
853 | 857 | return nbcon_context_can_proceed(ctxt, &cur); |
854 | 858 | } |
855 | 859 |
|
856 | | -static void nbcon_write_context_set_buf(struct nbcon_write_context *wctxt, |
857 | | - char *buf, unsigned int len) |
| 860 | +void nbcon_write_context_set_buf(struct nbcon_write_context *wctxt, |
| 861 | + char *buf, unsigned int len) |
858 | 862 | { |
859 | 863 | struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); |
860 | 864 | struct console *con = ctxt->console; |
@@ -1894,3 +1898,64 @@ void nbcon_device_release(struct console *con) |
1894 | 1898 | console_srcu_read_unlock(cookie); |
1895 | 1899 | } |
1896 | 1900 | EXPORT_SYMBOL_GPL(nbcon_device_release); |
| 1901 | + |
| 1902 | +/** |
| 1903 | + * nbcon_kdb_try_acquire - Try to acquire nbcon console and enter unsafe |
| 1904 | + * section |
| 1905 | + * @con: The nbcon console to acquire |
| 1906 | + * @wctxt: The nbcon write context to be used on success |
| 1907 | + * |
| 1908 | + * Context: Under console_srcu_read_lock() for emitting a single kdb message |
| 1909 | + * using the given con->write_atomic() callback. Can be called |
| 1910 | + * only when the console is usable at the moment. |
| 1911 | + * |
| 1912 | + * Return: True if the console was acquired. False otherwise. |
| 1913 | + * |
| 1914 | + * kdb emits messages on consoles registered for printk() without |
| 1915 | + * storing them into the ring buffer. It has to acquire the console |
| 1916 | + * ownerhip so that it could call con->write_atomic() callback a safe way. |
| 1917 | + * |
| 1918 | + * This function acquires the nbcon console using priority NBCON_PRIO_EMERGENCY |
| 1919 | + * and marks it unsafe for handover/takeover. |
| 1920 | + */ |
| 1921 | +bool nbcon_kdb_try_acquire(struct console *con, |
| 1922 | + struct nbcon_write_context *wctxt) |
| 1923 | +{ |
| 1924 | + struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); |
| 1925 | + |
| 1926 | + memset(ctxt, 0, sizeof(*ctxt)); |
| 1927 | + ctxt->console = con; |
| 1928 | + ctxt->prio = NBCON_PRIO_EMERGENCY; |
| 1929 | + |
| 1930 | + if (!nbcon_context_try_acquire(ctxt, false)) |
| 1931 | + return false; |
| 1932 | + |
| 1933 | + if (!nbcon_context_enter_unsafe(ctxt)) |
| 1934 | + return false; |
| 1935 | + |
| 1936 | + return true; |
| 1937 | +} |
| 1938 | + |
| 1939 | +/** |
| 1940 | + * nbcon_kdb_release - Exit unsafe section and release the nbcon console |
| 1941 | + * |
| 1942 | + * @wctxt: The nbcon write context initialized by a successful |
| 1943 | + * nbcon_kdb_try_acquire() |
| 1944 | + */ |
| 1945 | +void nbcon_kdb_release(struct nbcon_write_context *wctxt) |
| 1946 | +{ |
| 1947 | + struct nbcon_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); |
| 1948 | + |
| 1949 | + if (!nbcon_context_exit_unsafe(ctxt)) |
| 1950 | + return; |
| 1951 | + |
| 1952 | + nbcon_context_release(ctxt); |
| 1953 | + |
| 1954 | + /* |
| 1955 | + * Flush any new printk() messages added when the console was blocked. |
| 1956 | + * Only the console used by the given write context was blocked. |
| 1957 | + * The console was locked only when the write_atomic() callback |
| 1958 | + * was usable. |
| 1959 | + */ |
| 1960 | + __nbcon_atomic_flush_pending_con(ctxt->console, prb_next_reserve_seq(prb), false); |
| 1961 | +} |
0 commit comments