On Thu, Apr 22, 2021, Krish Sadhukhan wrote: > > On 4/22/21 10:50 AM, Krish Sadhukhan wrote: > > > > On 4/20/21 1:00 PM, Sean Christopherson wrote: > > > On Mon, Apr 12, 2021, Krish Sadhukhan wrote: > > > > According to APM vol 2, hardware ignores the low 12 bits in > > > > MSRPM and IOPM > > > > bitmaps. Therefore setting/unssetting these bits has no effect > > > > as far as > > > > VMRUN is concerned. Also, setting/unsetting these bits prevents > > > > tests from > > > > verifying hardware behavior. > > > > > > > > Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx> > > > > --- > > > > arch/x86/kvm/svm/nested.c | 2 -- > > > > 1 file changed, 2 deletions(-) > > > > > > > > diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c > > > > index ae53ae46ebca..fd42c8b7f99a 100644 > > > > --- a/arch/x86/kvm/svm/nested.c > > > > +++ b/arch/x86/kvm/svm/nested.c > > > > @@ -287,8 +287,6 @@ static void > > > > nested_load_control_from_vmcb12(struct vcpu_svm *svm, > > > > /* Copy it here because nested_svm_check_controls will > > > > check it. */ > > > > svm->nested.ctl.asid = control->asid; > > > > - svm->nested.ctl.msrpm_base_pa &= ~0x0fffULL; > > > > - svm->nested.ctl.iopm_base_pa &= ~0x0fffULL; > > > This will break nested_svm_vmrun_msrpm() if L1 passes an unaligned > > > address. > > > The shortlog is also wrong, KVM isn't setting bits, it's clearing bits. > > > > > > I also don't think svm->nested.ctl.msrpm_base_pa makes its way to > > > hardware; IIUC, > > > it's a copy of vmcs12->control.msrpm_base_pa. The bitmap that gets > > > loaded into > > > the "real" VMCB is vmcb02->control.msrpm_base_pa. > > > > > > Not sure if there's a problem with my patch as such, but upon inspecting > > the code, I see something missing: > > > > In nested_load_control_from_vmcb12(), we are not really loading > > msrpm_base_pa from vmcb12 even though the name of the function > > suggests so. > > > > Then nested_vmcb_check_controls() checks msrpm_base_pa from > > 'nested.ctl' which doesn't have the copy from vmcb12. > > > > Then nested_vmcb02_prepare_control() prepares the vmcb02 copy of > > msrpm_base_pa from vmcb01.ptr->control.msrpm_base_pa. > > > > Then nested_svm_vmrun_msrpm() uses msrpm_base_pa from 'nested.ctl'. > > > > > > Aren't we actually using msrpm_base_pa from vmcb01 instead of vmcb02 ? > > > Sorry, I meant to say, "from vmcb01 instead of vmcb12" The bitmap that's shoved into hardware comes from vmcb02, the bitmap that KVM reads to merge into _that_ bitmap comes from vmcb12. static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) { /* * This function merges the msr permission bitmaps of kvm and the * nested vmcb. It is optimized in that it only merges the parts where * the kvm msr permission bitmap may contain zero bits */ int i; if (!(vmcb_is_intercept(&svm->nested.ctl, INTERCEPT_MSR_PROT))) return true; for (i = 0; i < MSRPM_OFFSETS; i++) { u32 value, p; u64 offset; if (msrpm_offsets[i] == 0xffffffff) break; p = msrpm_offsets[i]; offset = svm->nested.ctl.msrpm_base_pa + (p * 4); if (kvm_vcpu_read_guest(&svm->vcpu, offset, &value, 4)) <- This reads vmcb12 return false; svm->nested.msrpm[p] = svm->msrpm[p] | value; <- Merge vmcb12's bitmap to KVM's bitmap for L2 } svm->vmcb->control.msrpm_base_pa = __sme_set(__pa(svm->nested.msrpm)); <- This is vmcb02 return true; }