x86/vpt: fix race when migrating timers between vCPUs
authorRoger Pau Monné <roger.pau@citrix.com>
Tue, 22 Sep 2020 14:10:37 +0000 (16:10 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 22 Sep 2020 14:10:37 +0000 (16:10 +0200)
commitfc8200a6ad5248d8fb6b0fbf3f3dc80f29dfe0c7
tree3707e7da2ea4cd09ebb8590ca541ab2e0d145cfa
parent5eab5f0543e4f5fc52f7e2d823a29a6b1567fc16
x86/vpt: fix race when migrating timers between vCPUs

The current vPT code will migrate the emulated timers between vCPUs
(change the pt->vcpu field) while just holding the destination lock,
either from create_periodic_time or pt_adjust_global_vcpu_target if
the global target is adjusted. Changing the periodic_timer vCPU field
in this way creates a race where a third party could grab the lock in
the unlocked region of pt_adjust_global_vcpu_target (or before
create_periodic_time performs the vcpu change) and then release the
lock from a different vCPU, creating a locking imbalance.

Introduce a per-domain rwlock in order to protect periodic_time
migration between vCPU lists. Taking the lock in read mode prevents
any timer from being migrated to a different vCPU, while taking it in
write mode allows performing migration of timers across vCPUs. The
per-vcpu locks are still used to protect all the other fields from the
periodic_timer struct.

Note that such migration shouldn't happen frequently, and hence
there's no performance drop as a result of such locking.

This is XSA-336.

Reported-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Tested-by: Igor Druzhinin <igor.druzhinin@citrix.com>
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/vpt.c
xen/include/asm-x86/hvm/vpt.h