• Olaf Hering's avatar
    xen: avoid crash in disable_hotplug_cpu · a502165d
    Olaf Hering authored
    [ Upstream commit 3366cdb6d350d95466ee430ac50f3c8415ca8f46 ]
    
    The command 'xl vcpu-set 0 0', issued in dom0, will crash dom0:
    
    BUG: unable to handle kernel NULL pointer dereference at 00000000000002d8
    PGD 0 P4D 0
    Oops: 0000 [#1] PREEMPT SMP NOPTI
    CPU: 7 PID: 65 Comm: xenwatch Not tainted 4.19.0-rc2-1.ga9462db-default #1 openSUSE Tumbleweed (unreleased)
    Hardware name: Intel Corporation S5520UR/S5520UR, BIOS S5500.86B.01.00.0050.050620101605 05/06/2010
    RIP: e030:device_offline+0x9/0xb0
    Code: 77 24 00 e9 ce fe ff ff 48 8b 13 e9 68 ff ff ff 48 8b 13 e9 29 ff ff ff 48 8b 13 e9 ea fe ff ff 90 66 66 66 66 90 41 54 55 53 <f6> 87 d8 02 00 00 01 0f 85 88 00 00 00 48 c7 c2 20 09 60 81 31 f6
    RSP: e02b:ffffc90040f27e80 EFLAGS: 00010203
    RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
    RDX: ffff8801f3800000 RSI: ffffc90040f27e70 RDI: 0000000000000000
    RBP: 0000000000000000 R08: ffffffff820e47b3 R09: 0000000000000000
    R10: 0000000000007ff0 R11: 0000000000000000 R12: ffffffff822e6d30
    R13: dead000000000200 R14: dead000000000100 R15: ffffffff8158b4e0
    FS:  00007ffa595158c0(0000) GS:ffff8801f39c0000(0000) knlGS:0000000000000000
    CS:  e033 DS: 0000 ES: 0000 CR0: 0000000080050033
    CR2: 00000000000002d8 CR3: 00000001d9602000 CR4: 0000000000002660
    Call Trace:
     handle_vcpu_hotplug_event+0xb5/0xc0
     xenwatch_thread+0x80/0x140
     ? wait_woken+0x80/0x80
     kthread+0x112/0x130
     ? kthread_create_worker_on_cpu+0x40/0x40
     ret_from_fork+0x3a/0x50
    
    This happens because handle_vcpu_hotplug_event is called twice. In the
    first iteration cpu_present is still true, in the second iteration
    cpu_present is false which causes get_cpu_device to return NULL.
    In case of cpu#0, cpu_online is apparently always true.
    
    Fix this crash by checking if the cpu can be hotplugged, which is false
    for a cpu that was just removed.
    
    Also check if the cpu was actually offlined by device_remove, otherwise
    leave the cpu_present state as it is.
    
    Rearrange to code to do all work with device_hotplug_lock held.
    Signed-off-by: 's avatarOlaf Hering <olaf@aepfle.de>
    Reviewed-by: 's avatarJuergen Gross <jgross@suse.com>
    Signed-off-by: 's avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
    Signed-off-by: 's avatarSasha Levin <alexander.levin@microsoft.com>
    Signed-off-by: 's avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    a502165d