On Fri, 2023-03-03 at 23:53 +0800, Chao Gao wrote: > On Fri, Mar 03, 2023 at 10:23:50PM +0800, Robert Hoo wrote: > > On Fri, 2023-03-03 at 14:21 +0800, Chao Gao wrote: > > > On Mon, Feb 27, 2023 at 04:45:45PM +0800, Robert Hoo wrote: > > > > LAM feature uses 2 high bits in CR3 (bit 62 for LAM_U48 and bit > > > > 61 > > > > for > > > > LAM_U57) to enable/config LAM feature for user mode addresses. > > > > The > > > > LAM > > > > masking is done before legacy canonical checks. > > > > > > > > To virtualize LAM CR3 bits usage, this patch: > > > > 1. Don't reserve these 2 bits when LAM is enable on the vCPU. > > > > Previously > > > > when validate CR3, kvm uses kvm_vcpu_is_legal_gpa(), now define > > > > kvm_vcpu_is_valid_cr3() which is actually > > > > kvm_vcpu_is_legal_gpa() > > > > + CR3.LAM bits validation. Substitutes > > > > kvm_vcpu_is_legal/illegal_gpa() > > > > with kvm_vcpu_is_valid_cr3() in call sites where is validating > > > > CR3 > > > > rather > > > > than pure GPA. > > > > 2. mmu::get_guest_pgd(), its implementation is get_cr3() which > > > > returns > > > > whole guest CR3 value. Strip LAM bits in those call sites that > > > > need > > > > pure > > > > PGD value, e.g. mmu_alloc_shadow_roots(), > > > > FNAME(walk_addr_generic)(). > > > > 3. When form a new guest CR3 (vmx_load_mmu_pgd()), melt in LAM > > > > bit > > > > (kvm_get_active_lam()). > > > > 4. When guest sets CR3, identify ONLY-LAM-bits-toggling cases, > > > > where it is > > > > unnecessary to make new pgd, but just make request of load pgd, > > > > then new > > > > CR3.LAM bits configuration will be melt in (above point 3). To > > > > be > > > > conservative, this case still do TLB flush. > > > > 5. For nested VM entry, allow the 2 CR3 bits set in > > > > corresponding > > > > VMCS host/guest fields. > > > > > > isn't this already covered by item #1 above? > > > > Ah, it is to address your comments on last version. To > > repeat/emphasize > > again, doesn't harm, does it?;) > > It is confusing. Trying to merge #5 to #1: Well this is kind of subjective. I don't have any bias on this. > > If LAM is supported, bits 62:61 (LAM_U48 and LAM_U57) are not > reserved > in CR3. VM entry also allows the two bits to be set in CR3 field in > guest-state and host-state area of the VMCS. Previously ... > > > > > > > > (...) > > > > > > > > +static inline u64 kvm_get_active_lam(struct kvm_vcpu *vcpu) > > > > +{ > > > > + return kvm_read_cr3(vcpu) & (X86_CR3_LAM_U48 | > > > > X86_CR3_LAM_U57); > > > > +} > > > > > > I think it is better to define a mask (like reserved_gpa_bits): > > > > > > kvm_vcpu_arch { > > > ... > > > > > > /* > > > * Bits in CR3 used to enable certain features. These bits > > > don't > > > * participate in page table walking. They should be masked to > > > * get the base address of page table. When shadow paging is > > > * used, these bits should be kept as is in the shadow CR3. > > > */ > > > u64 cr3_control_bits; > > > > > > > I don't strongly object this. But per SDM, CR3.bit[63:MAXPHYADDR] > > are > > reserved; and MAXPHYADDR is at most 52 [1]. So can we assert and > > simply > > define the MASK bit[63:52]? (I did this in v3 and prior) > > No. Setting any bit in 60:52 should be rejected. And setting bit 62 > or > 61 should be allowed if LAM is supported by the vCPU. I don't see how > your proposal can distinguish these two cases. No you didn't get my point. Perhaps you can take a look at v3 patch and prior https://lore.kernel.org/kvm/20221209044557.1496580-4-robert.hu@xxxxxxxxxxxxxxx/ define CR3_HIGH_RSVD_MASK, given "MAXPHYADDR is at most 52" is stated in SDM.