platform_kernel-5.15/drivers/char
Amit Shah ea3768b438 virtio: console: clean up port data immediately at time of unplug
We used to keep the port's char device structs and the /sys entries
around till the last reference to the port was dropped.  This is
actually unnecessary, and resulted in buggy behaviour:

1. Open port in guest
2. Hot-unplug port
3. Hot-plug a port with the same 'name' property as the unplugged one

This resulted in hot-plug being unsuccessful, as a port with the same
name already exists (even though it was unplugged).

This behaviour resulted in a warning message like this one:

-------------------8<---------------------------------------
WARNING: at fs/sysfs/dir.c:512 sysfs_add_one+0xc9/0x130() (Not tainted)
Hardware name: KVM
sysfs: cannot create duplicate filename
'/devices/pci0000:00/0000:00:04.0/virtio0/virtio-ports/vport0p1'

Call Trace:
 [<ffffffff8106b607>] ? warn_slowpath_common+0x87/0xc0
 [<ffffffff8106b6f6>] ? warn_slowpath_fmt+0x46/0x50
 [<ffffffff811f2319>] ? sysfs_add_one+0xc9/0x130
 [<ffffffff811f23e8>] ? create_dir+0x68/0xb0
 [<ffffffff811f2469>] ? sysfs_create_dir+0x39/0x50
 [<ffffffff81273129>] ? kobject_add_internal+0xb9/0x260
 [<ffffffff812733d8>] ? kobject_add_varg+0x38/0x60
 [<ffffffff812734b4>] ? kobject_add+0x44/0x70
 [<ffffffff81349de4>] ? get_device_parent+0xf4/0x1d0
 [<ffffffff8134b389>] ? device_add+0xc9/0x650

-------------------8<---------------------------------------

Instead of relying on guest applications to release all references to
the ports, we should go ahead and unregister the port from all the core
layers.  Any open/read calls on the port will then just return errors,
and an unplug/plug operation on the host will succeed as expected.

This also caused buggy behaviour in case of the device removal (not just
a port): when the device was removed (which means all ports on that
device are removed automatically as well), the ports with active
users would clean up only when the last references were dropped -- and
it would be too late then to be referencing char device pointers,
resulting in oopses:

-------------------8<---------------------------------------
PID: 6162   TASK: ffff8801147ad500  CPU: 0   COMMAND: "cat"
 #0 [ffff88011b9d5a90] machine_kexec at ffffffff8103232b
 #1 [ffff88011b9d5af0] crash_kexec at ffffffff810b9322
 #2 [ffff88011b9d5bc0] oops_end at ffffffff814f4a50
 #3 [ffff88011b9d5bf0] die at ffffffff8100f26b
 #4 [ffff88011b9d5c20] do_general_protection at ffffffff814f45e2
 #5 [ffff88011b9d5c50] general_protection at ffffffff814f3db5
    [exception RIP: strlen+2]
    RIP: ffffffff81272ae2  RSP: ffff88011b9d5d00  RFLAGS: 00010246
    RAX: 0000000000000000  RBX: ffff880118901c18  RCX: 0000000000000000
    RDX: ffff88011799982c  RSI: 00000000000000d0  RDI: 3a303030302f3030
    RBP: ffff88011b9d5d38   R8: 0000000000000006   R9: ffffffffa0134500
    R10: 0000000000001000  R11: 0000000000001000  R12: ffff880117a1cc10
    R13: 00000000000000d0  R14: 0000000000000017  R15: ffffffff81aff700
    ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
 #6 [ffff88011b9d5d00] kobject_get_path at ffffffff8126dc5d
 #7 [ffff88011b9d5d40] kobject_uevent_env at ffffffff8126e551
 #8 [ffff88011b9d5dd0] kobject_uevent at ffffffff8126e9eb
 #9 [ffff88011b9d5de0] device_del at ffffffff813440c7

-------------------8<---------------------------------------

So clean up when we have all the context, and all that's left to do when
the references to the port have dropped is to free up the port struct
itself.

CC: <stable@vger.kernel.org>
Reported-by: chayang <chayang@redhat.com>
Reported-by: YOGANANTH SUBRAMANIAN <anantyog@in.ibm.com>
Reported-by: FuXiangChun <xfu@redhat.com>
Reported-by: Qunfang Zhang <qzhang@redhat.com>
Reported-by: Sibiao Luo <sluo@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2013-07-29 14:43:56 +09:30
..
agp Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux 2013-07-09 16:04:31 -07:00
hw_random Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus 2013-07-13 14:52:21 -07:00
ipmi char: Convert use of typedef ctl_table to struct ctl_table 2013-06-17 16:43:08 -07:00
mwave mwave: fix info leak in mwave_ioctl() 2013-07-09 10:33:28 -07:00
pcmcia Finally eradicate CONFIG_HOTPLUG 2013-06-03 14:20:18 -07:00
tpm tpm/tpm_i2c_infineon: Remove unused header file 2013-06-28 00:47:43 +02:00
xilinx_hwicap char: xilinx_hwicap: Fix typo in comment and extend it 2013-05-30 21:46:16 +09:00
Kconfig stallion: final cleanup 2013-06-03 14:31:39 -07:00
Makefile IPMI: Change link order 2012-10-16 18:07:12 -07:00
apm-emulation.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/apm 2012-04-05 17:34:30 -07:00
applicom.c applicom: use correct array offset 2013-03-15 12:23:48 -07:00
applicom.h
bfin-otp.c
bsr.c powerpc/BSR: cleanup the error path of bsr_init 2012-07-17 10:27:38 -07:00
ds1302.c Remove all #inclusions of asm/system.h 2012-03-28 18:30:03 +01:00
ds1620.c ds1620: single_open() leak 2013-05-05 00:11:29 -04:00
dsp56k.c new helper: file_inode(file) 2013-02-22 23:31:31 -05:00
dtlk.c new helper: file_inode(file) 2013-02-22 23:31:31 -05:00
efirtc.c rtc: single_open() leaks 2013-05-05 00:12:29 -04:00
generic_nvram.c drivers: fix up various ->llseek() implementations 2011-07-20 20:47:58 -04:00
genrtc.c rtc: single_open() leaks 2013-05-05 00:12:29 -04:00
hangcheck-timer.c
hpet.c char: Convert use of typedef ctl_table to struct ctl_table 2013-06-17 16:43:08 -07:00
i8k.c module_param: make bool parameters really bool (drivers & misc) 2012-01-13 09:32:20 +10:30
lp.c Char: lp, protect LPGETSTATUS with port_mutex 2013-05-16 18:08:58 -07:00
mbcs.c char: remove use of __devinitconst 2012-11-21 12:55:19 -08:00
mbcs.h Fix common misspellings 2011-03-31 11:26:23 -03:00
mem.c /dev/oldmem: Remove the interface 2013-07-03 16:08:03 -07:00
misc.c Revert "char: misc: assign file->private_data in all cases" 2013-06-26 10:12:48 -07:00
mmtimer.c drivers/char/mmtimer.c: Remove useless kfree 2012-09-26 13:20:40 -07:00
msm_smd_pkt.c drivers/char/msm_smd_pkt.c: don't use IS_ERR() 2011-08-25 16:25:33 -07:00
mspec.c char: Use vma_pages() to replace (vm_end - vm_start) >> PAGE_SHIFT 2013-05-21 10:07:54 -07:00
nsc_gpio.c new helper: file_inode(file) 2013-02-22 23:31:31 -05:00
nvram.c Remove all #inclusions of asm/system.h 2012-03-28 18:30:03 +01:00
nwbutton.c drivers/char: removes unnecessary semicolon 2012-09-26 13:20:39 -07:00
nwbutton.h
nwflash.c Merge branch 'late/fixes' into fixes 2012-10-07 07:22:32 -07:00
pc8736x_gpio.c pc8736x_gpio: use platform_device_unregister in pc8736x_gpio_cleanup() 2012-10-24 15:52:29 -07:00
ppdev.c new helper: file_inode(file) 2013-02-22 23:31:31 -05:00
ps3flash.c ps3flash: switch to generic_file_llseek_size() 2013-06-29 12:57:33 +04:00
random.c char: Convert use of typedef ctl_table to struct ctl_table 2013-06-17 16:43:08 -07:00
raw.c new helper: file_inode(file) 2013-02-22 23:31:31 -05:00
rtc.c char: Convert use of typedef ctl_table to struct ctl_table 2013-06-17 16:43:08 -07:00
scx200_gpio.c
snsc.c Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl 2010-10-22 10:52:56 -07:00
snsc.h headers: kobject.h redux 2011-01-10 08:51:44 -08:00
snsc_event.c
sonypi.c Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2013-02-26 20:16:07 -08:00
tb0219.c new helper: file_inode(file) 2013-02-22 23:31:31 -05:00
tile-srom.c tile-srom: switch to fixed_size_llseek() 2013-06-29 12:57:51 +04:00
tlclk.c drivers/char/tlclk.c: fix error return code 2012-08-16 10:09:15 -07:00
toshiba.c Merge branch 'llseek' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/bkl 2010-10-22 10:52:56 -07:00
ttyprintk.c ttyprintk: Fix NULL pointer deref by setting tty_port ops after initializing port 2013-05-21 10:13:23 -07:00
uv_mmtimer.c BKL: remove extraneous #include <smp_lock.h> 2010-11-17 08:59:32 -08:00
virtio_console.c virtio: console: clean up port data immediately at time of unplug 2013-07-29 14:43:56 +09:30