public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Yosry Ahmed <yosry.ahmed@linux.dev>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	Jim Mattson <jmattson@google.com>,
	kvm@vger.kernel.org,  linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 12/23] KVM: selftests: Parameterize the PTE bitmasks for virt mapping functions
Date: Thu, 20 Nov 2025 16:07:27 -0800	[thread overview]
Message-ID: <aR-tP8YBftwZA3DD@google.com> (raw)
In-Reply-To: <20251021074736.1324328-13-yosry.ahmed@linux.dev>

On Tue, Oct 21, 2025, Yosry Ahmed wrote:
> @@ -1367,8 +1357,6 @@ static inline bool kvm_is_ignore_msrs(void)
>  	return get_kvm_param_bool("ignore_msrs");
>  }
>  
> -uint64_t *__vm_get_page_table_entry(struct kvm_vm *vm, uint64_t vaddr,
> -				    int *level);
>  uint64_t *vm_get_page_table_entry(struct kvm_vm *vm, uint64_t vaddr);
>  
>  uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2,
> @@ -1451,7 +1439,20 @@ enum pg_level {
>  #define PG_SIZE_2M PG_LEVEL_SIZE(PG_LEVEL_2M)
>  #define PG_SIZE_1G PG_LEVEL_SIZE(PG_LEVEL_1G)
>  
> -void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level);
> +struct pte_masks {
> +	uint64_t present;
> +	uint64_t writeable;
> +	uint64_t user;
> +	uint64_t accessed;
> +	uint64_t dirty;
> +	uint64_t large;

Ugh, "large".  I vote for "huge" or "hugepage", as that's for more ubiquitous in
the kernel.

> +	uint64_t nx;

The values themselves should be const, e.g. to communicate that they are fixed
values.

> +};
> +
> +extern const struct pte_masks x86_pte_masks;

> -void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level)
> +void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,
> +		   int level, const struct pte_masks *masks)
>  {
>  	const uint64_t pg_size = PG_LEVEL_SIZE(level);
>  	uint64_t *pte = &vm->pgd;
> @@ -246,16 +259,16 @@ void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level)
>  	 * early if a hugepage was created.
>  	 */
>  	for (current_level = vm->pgtable_levels; current_level > PG_LEVEL_4K; current_level--) {
> -		pte = virt_create_upper_pte(vm, pte, vaddr, paddr, current_level, level);
> -		if (*pte & PTE_LARGE_MASK)
> +		pte = virt_create_upper_pte(vm, pte, vaddr, paddr, current_level, level, masks);
> +		if (*pte & masks->large)
>  			return;
>  	}
>  
>  	/* Fill in page table entry. */
> -	pte = virt_get_pte(vm, pte, vaddr, PG_LEVEL_4K);
> -	TEST_ASSERT(!(*pte & PTE_PRESENT_MASK),
> +	pte = virt_get_pte(vm, pte, vaddr, PG_LEVEL_4K, masks);
> +	TEST_ASSERT(!(*pte & masks->present),

I think accessors would help for the "read" cases?  E.g.

	TEST_ASSERT(!is_present_pte(mmu, *pte)

or maybe go with a slightly atypical ordering of:

	TEST_ASSERT(!is_present_pte(*pte, mmu),

The second one seems more readable.

>  		    "PTE already present for 4k page at vaddr: 0x%lx", vaddr);
> -	*pte = PTE_PRESENT_MASK | PTE_WRITABLE_MASK | (paddr & PHYSICAL_PAGE_MASK);
> +	*pte = masks->present | masks->writeable | (paddr & PHYSICAL_PAGE_MASK);

Hrm.  I don't love the masks->lowercase style, but I don't hate it either.  One
idea would be to add macros to grab the correct bit, e.g.

	*pte = PTE_PRESENT(mmu) | PTE_WRITABLE(mmu) | (paddr & PHYSICAL_PAGE_MASK);

Alternatively, assuming we add "struct kvm_mmu", we could grab the "pte_masks"
structure locally as "m" and do this?  Note sure the super-shorthand is a net
positive though.

	*pte = PTE_PRESENT(m) | PTE_WRITABLE(m) | (paddr & PHYSICAL_PAGE_MASK);

Or we could YELL REALLY LOUDLY in the fields themselves, e.g.

	*pte = m->PRESENT | m->WRITABLE | (paddr & PHYSICAL_PAGE_MASK);

but that looks kinda weird to me.

I don't have a super strong preference, though I'm leaning towards accessor
functions with macros for retrieving the bits.

>  	/*
>  	 * Neither SEV nor TDX supports shared page tables, so only the final

Hiding just out of sight is this code:

	/*
	 * Neither SEV nor TDX supports shared page tables, so only the final
	 * leaf PTE needs manually set the C/S-bit.
	 */
	if (vm_is_gpa_protected(vm, paddr))
		*pte |= vm->arch.c_bit;
	else
		*pte |= vm->arch.s_bit;

The C-bit (enCrypted) and S-bit (Shared) values need to be moved into the masks/mmu
context as well.  In practice, they'll both be zero when creating nested mappings
since KVM doesn't support nested VMs with encrypted memory, but it's still wrong,
e.g. the Shared bit doesn't exist in EPT.

  reply	other threads:[~2025-11-21  0:07 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-21  7:47 [PATCH v2 00/23] Extend test coverage for nested SVM Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 01/23] KVM: selftests: Minor improvements to asserts in test_vmx_nested_state() Yosry Ahmed
2025-11-20 23:40   ` Sean Christopherson
2025-11-20 23:46     ` Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 02/23] KVM: selftests: Extend vmx_set_nested_state_test to cover SVM Yosry Ahmed
2025-11-20 23:52   ` Sean Christopherson
2025-10-21  7:47 ` [PATCH v2 03/23] KVM: selftests: Extend vmx_close_while_nested_test " Yosry Ahmed
2025-11-20 23:53   ` Sean Christopherson
2025-10-21  7:47 ` [PATCH v2 04/23] KVM: selftests: Extend vmx_nested_tsc_scaling_test " Yosry Ahmed
2025-11-20 23:54   ` Sean Christopherson
2025-10-21  7:47 ` [PATCH v2 05/23] KVM: selftests: Move nested invalid CR3 check to its own test Yosry Ahmed
2025-11-20 23:55   ` Sean Christopherson
2025-10-21  7:47 ` [PATCH v2 06/23] KVM: selftests: Extend nested_invalid_cr3_test to cover SVM Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 07/23] KVM: selftests: Extend vmx_tsc_adjust_test " Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 08/23] KVM: selftests: Stop hardcoding PAGE_SIZE in x86 selftests Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 09/23] KVM: selftests: Remove the unused argument to prepare_eptp() Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 10/23] KVM: selftests: Stop using __virt_pg_map() directly in tests Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 11/23] KVM: selftests: Make sure vm->vpages_mapped is always up-to-date Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 12/23] KVM: selftests: Parameterize the PTE bitmasks for virt mapping functions Yosry Ahmed
2025-11-21  0:07   ` Sean Christopherson [this message]
2025-11-21  0:18     ` Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 13/23] KVM: selftests: Pass the root GPA into virt_get_pte() Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 14/23] KVM: selftests: Pass the root GPA into __virt_pg_map() Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 15/23] KVM: selftests: Stop setting AD bits on nested EPTs on creation Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 16/23] KVM: selftests: Use __virt_pg_map() for nested EPTs Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 17/23] KVM: selftests: Kill eptPageTablePointer Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 18/23] KVM: selftests: Generalize nested mapping functions Yosry Ahmed
2025-11-21  0:10   ` Sean Christopherson
2025-11-21  0:20     ` Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 19/23] KVM: selftests: Move nested MMU mapping functions outside of vmx.c Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 20/23] KVM: selftests: Stop passing a memslot to nested_map_memslot() Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 21/23] KVM: selftests: Allow kvm_cpu_has_ept() to be called on AMD CPUs Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 22/23] KVM: selftests: Set the user bit on nested MMU PTEs Yosry Ahmed
2025-10-21  7:47 ` [PATCH v2 23/23] KVM: selftests: Extend vmx_dirty_log_test to cover SVM Yosry Ahmed
2025-10-29 14:24 ` [PATCH v2 00/23] Extend test coverage for nested SVM Yosry Ahmed
2025-11-18 22:25 ` Yosry Ahmed
2025-11-18 23:00   ` Jim Mattson
2025-11-18 23:22     ` Yosry Ahmed
2025-11-18 23:49       ` Sean Christopherson
2025-11-19  0:01         ` Yosry Ahmed
2025-11-19  0:07           ` Sean Christopherson
2025-11-20 23:51           ` Sean Christopherson
2025-11-20 23:23 ` Sean Christopherson
2025-11-20 23:32   ` Yosry Ahmed
2025-11-20 23:50 ` Sean Christopherson
2025-11-21  0:05   ` Yosry Ahmed
2025-11-21  0:24     ` Sean Christopherson
2025-11-21  0:30       ` Yosry Ahmed
2025-11-21 18:55 ` Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aR-tP8YBftwZA3DD@google.com \
    --to=seanjc@google.com \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=yosry.ahmed@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox