Skip to content

Commit de1fca5

Browse files
committed
KVM: x86: do not modify masked bits of shared MSRs
"Shared MSRs" are guest MSRs that are written to the host MSRs but keep their value until the next return to userspace. They support a mask, so that some bits keep the host value, but this mask is only used to skip an unnecessary MSR write and the value written to the MSR is always the guest MSR. Fix this and, while at it, do not update smsr->values[slot].curr if for whatever reason the wrmsr fails. This should only happen due to reserved bits, so the value written to smsr->values[slot].curr will not match when the user-return notifier and the host value will always be restored. However, it is untidy and in rare cases this can actually avoid spurious WRMSRs on return to userspace. Cc: [email protected] Reviewed-by: Jim Mattson <[email protected]> Tested-by: Jim Mattson <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent cbbaa27 commit de1fca5

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

arch/x86/kvm/x86.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,13 +300,14 @@ int kvm_set_shared_msr(unsigned slot, u64 value, u64 mask)
300300
struct kvm_shared_msrs *smsr = per_cpu_ptr(shared_msrs, cpu);
301301
int err;
302302

303-
if (((value ^ smsr->values[slot].curr) & mask) == 0)
303+
value = (value & mask) | (smsr->values[slot].host & ~mask);
304+
if (value == smsr->values[slot].curr)
304305
return 0;
305-
smsr->values[slot].curr = value;
306306
err = wrmsrl_safe(shared_msrs_global.msrs[slot], value);
307307
if (err)
308308
return 1;
309309

310+
smsr->values[slot].curr = value;
310311
if (!smsr->registered) {
311312
smsr->urn.on_user_return = kvm_on_user_return;
312313
user_return_notifier_register(&smsr->urn);

0 commit comments

Comments
 (0)