mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-28 20:02:17 +00:00
![Daniel Vetter](/assets/img/avatar_default.png)
console_unblank() does this too (called in both places right after), and with a lot more confidence inspiring approach to locking. Reconstructing this story is very strange: Inb61312d353
("oops handling: ensure that any oops is flushed to the mtdoops console") it is claimed that a printk(" "); flushed out the console buffer, which was removed ine3e8a75d2a
("[PATCH] Extract and use wake_up_klogd()"). In todays kernels this is done way earlier in console_flush_on_panic with some really nasty tricks. I didn't bother to fully reconstruct this all, least because the call to bust_spinlock(0); gets moved every few years, depending upon how the wind blows (or well, who screamed loudest about the various issue each call site caused). Before that commit the only calls to console_unblank() where in s390 arch code. The other side here is the console->unblank callback, which was introduced in 2.1.31 for the vt driver. Which predates the console_unblank() function by a lot, which was added (without users) in 2.4.14.3. So pretty much impossible to guess at any motivation here. Also afaict the vt driver is the only (and always was the only) console driver implementing the unblank callback, so no idea why a call to console_unblank() was added for the mtdooops driver - the action actually flushing out the console buffers is done from console_unlock() only. Note that as prep for the s390 users the locking was adjusted in 2.5.22 (I couldn't figure out how to properly reference the BK commit from the historical git trees) from a normal semaphore to a trylock. Note that a copy of the direct unblank_screen() call was added to panic() inc7c3f05e34
("panic: avoid deadlocks in re-entrant console drivers"), which partially inlined the bust_spinlocks(0); call. Long story short, I have no idea why the direct call to unblank_screen survived for so long (the infrastructure to do it properly existed for years), nor why it wasn't removed when the console_unblank() call was finally added. But it makes a ton more sense to finally do that than not - it's just better encapsulation to go through the console functions instead of doing a direct call, so let's dare. Plus it really does not make much sense to call the only unblank implementation there is twice, once without, and once with appropriate locking. Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Jiri Slaby <jirislaby@kernel.org> Cc: Daniel Vetter <daniel.vetter@ffwll.ch> Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com> Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Cc: Xuezhi Zhang <zhangxuezhi1@coolpad.com> Cc: Yangxi Xiang <xyangxi5@gmail.com> Cc: nick black <dankamongmen@gmail.com> Cc: Petr Mladek <pmladek@suse.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Luis Chamberlain <mcgrof@kernel.org> Cc: "Guilherme G. Piccoli" <gpiccoli@igalia.com> Cc: Marco Elver <elver@google.com> Cc: John Ogness <john.ogness@linutronix.de> Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Cc: David Gow <davidgow@google.com> Cc: tangmeng <tangmeng@uniontech.com> Cc: Tiezhu Yang <yangtiezhu@loongson.cn> Cc: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Petr Mladek <pmladek@suse.com> Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Link: https://lore.kernel.org/r/20220830145004.430545-1-daniel.vetter@ffwll.ch Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
174 lines
5.3 KiB
C
174 lines
5.3 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _VT_KERN_H
|
|
#define _VT_KERN_H
|
|
|
|
/*
|
|
* this really is an extension of the vc_cons structure in console.c, but
|
|
* with information needed by the vt package
|
|
*/
|
|
|
|
#include <linux/vt.h>
|
|
#include <linux/kd.h>
|
|
#include <linux/tty.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/console_struct.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/consolemap.h>
|
|
#include <linux/notifier.h>
|
|
|
|
void kd_mksound(unsigned int hz, unsigned int ticks);
|
|
int kbd_rate(struct kbd_repeat *rep);
|
|
|
|
extern int fg_console, last_console, want_console;
|
|
|
|
/* console.c */
|
|
|
|
int vc_allocate(unsigned int console);
|
|
int vc_cons_allocated(unsigned int console);
|
|
int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines);
|
|
struct vc_data *vc_deallocate(unsigned int console);
|
|
void reset_palette(struct vc_data *vc);
|
|
void do_blank_screen(int entering_gfx);
|
|
void do_unblank_screen(int leaving_gfx);
|
|
void poke_blanked_console(void);
|
|
int con_font_op(struct vc_data *vc, struct console_font_op *op);
|
|
int con_set_cmap(unsigned char __user *cmap);
|
|
int con_get_cmap(unsigned char __user *cmap);
|
|
void scrollback(struct vc_data *vc);
|
|
void scrollfront(struct vc_data *vc, int lines);
|
|
void clear_buffer_attributes(struct vc_data *vc);
|
|
void update_region(struct vc_data *vc, unsigned long start, int count);
|
|
void redraw_screen(struct vc_data *vc, int is_switch);
|
|
#define update_screen(x) redraw_screen(x, 0)
|
|
#define switch_screen(x) redraw_screen(x, 1)
|
|
|
|
struct tty_struct;
|
|
int tioclinux(struct tty_struct *tty, unsigned long arg);
|
|
|
|
#ifdef CONFIG_CONSOLE_TRANSLATIONS
|
|
/* consolemap.c */
|
|
|
|
struct unipair;
|
|
|
|
int con_set_trans_old(unsigned char __user * table);
|
|
int con_get_trans_old(unsigned char __user * table);
|
|
int con_set_trans_new(unsigned short __user * table);
|
|
int con_get_trans_new(unsigned short __user * table);
|
|
int con_clear_unimap(struct vc_data *vc);
|
|
int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list);
|
|
int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct, struct unipair __user *list);
|
|
int con_set_default_unimap(struct vc_data *vc);
|
|
void con_free_unimap(struct vc_data *vc);
|
|
int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc);
|
|
|
|
#else
|
|
static inline int con_set_trans_old(unsigned char __user *table)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int con_get_trans_old(unsigned char __user *table)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
static inline int con_set_trans_new(unsigned short __user *table)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline int con_get_trans_new(unsigned short __user *table)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
static inline int con_clear_unimap(struct vc_data *vc)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline
|
|
int con_set_unimap(struct vc_data *vc, ushort ct, struct unipair __user *list)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline
|
|
int con_get_unimap(struct vc_data *vc, ushort ct, ushort __user *uct,
|
|
struct unipair __user *list)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
static inline int con_set_default_unimap(struct vc_data *vc)
|
|
{
|
|
return 0;
|
|
}
|
|
static inline void con_free_unimap(struct vc_data *vc)
|
|
{
|
|
}
|
|
static inline void con_protect_unimap(struct vc_data *vc, int rdonly)
|
|
{
|
|
}
|
|
static inline
|
|
int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
/* vt.c */
|
|
void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
|
|
int vt_waitactive(int n);
|
|
void change_console(struct vc_data *new_vc);
|
|
void reset_vc(struct vc_data *vc);
|
|
int do_unbind_con_driver(const struct consw *csw, int first, int last,
|
|
int deflt);
|
|
int vty_init(const struct file_operations *console_fops);
|
|
|
|
extern bool vt_dont_switch;
|
|
extern int default_utf8;
|
|
extern int global_cursor_default;
|
|
|
|
struct vt_spawn_console {
|
|
spinlock_t lock;
|
|
struct pid *pid;
|
|
int sig;
|
|
};
|
|
extern struct vt_spawn_console vt_spawn_con;
|
|
|
|
int vt_move_to_console(unsigned int vt, int alloc);
|
|
|
|
/* Interfaces for VC notification of character events (for accessibility etc) */
|
|
|
|
struct vt_notifier_param {
|
|
struct vc_data *vc; /* VC on which the update happened */
|
|
unsigned int c; /* Printed char */
|
|
};
|
|
|
|
int register_vt_notifier(struct notifier_block *nb);
|
|
int unregister_vt_notifier(struct notifier_block *nb);
|
|
|
|
void hide_boot_cursor(bool hide);
|
|
|
|
/* keyboard provided interfaces */
|
|
int vt_do_diacrit(unsigned int cmd, void __user *up, int eperm);
|
|
int vt_do_kdskbmode(unsigned int console, unsigned int arg);
|
|
int vt_do_kdskbmeta(unsigned int console, unsigned int arg);
|
|
int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc,
|
|
int perm);
|
|
int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
|
|
unsigned int console);
|
|
int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm);
|
|
int vt_do_kdskled(unsigned int console, int cmd, unsigned long arg, int perm);
|
|
int vt_do_kdgkbmode(unsigned int console);
|
|
int vt_do_kdgkbmeta(unsigned int console);
|
|
void vt_reset_unicode(unsigned int console);
|
|
int vt_get_shift_state(void);
|
|
void vt_reset_keyboard(unsigned int console);
|
|
int vt_get_leds(unsigned int console, int flag);
|
|
int vt_get_kbd_mode_bit(unsigned int console, int bit);
|
|
void vt_set_kbd_mode_bit(unsigned int console, int bit);
|
|
void vt_clr_kbd_mode_bit(unsigned int console, int bit);
|
|
void vt_set_led_state(unsigned int console, int leds);
|
|
void vt_kbd_con_start(unsigned int console);
|
|
void vt_kbd_con_stop(unsigned int console);
|
|
|
|
void vc_scrolldelta_helper(struct vc_data *c, int lines,
|
|
unsigned int rolled_over, void *_base, unsigned int size);
|
|
|
|
#endif /* _VT_KERN_H */
|