From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f74.google.com (mail-pj1-f74.google.com [209.85.216.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6FE76227EB9 for ; Tue, 23 Dec 2025 23:12:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.74 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766531533; cv=none; b=E5LEIKQpAC06OrCXmm1CNIAEK0+QaY0/MvP8g0fiITQqz8sH43q7Z8I5bs7VFAr9XrndnUQziwPgF22BvcfEziLCVRy4+1BjkzllnKx5KyQ0qL2JjqStoONxm070WU9mzR4qssPdWuvC0DcRJd/PEQL0evL6fnGLjThxMvhHRR4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1766531533; c=relaxed/simple; bh=wN65EApT/ayEKiqDm9SizlLSn1y2MGXxbsfB1NdKD1Q=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=r1HeHk0z93DTNbTc/7+3x6K34O4IKKDz5ejm8am8V4h23ZfWHxfAN1dyemb4lfBX3cUKJaweKmW5hSOaL9knmaYE3MODpCCRvKeVoczcvhLGQOFA6jkWmL2E29M3xTsa+PAYBqKZVs8mYxbeWaGuqkmf/wQ/NgWRExGirK8EjzM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=V36QEEiB; arc=none smtp.client-ip=209.85.216.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--seanjc.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="V36QEEiB" Received: by mail-pj1-f74.google.com with SMTP id 98e67ed59e1d1-34c5d203988so11308451a91.3 for ; Tue, 23 Dec 2025 15:12:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1766531531; x=1767136331; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=xEi01BqSTkmwBMdWxitsf6rmzRbefuQ2j6agJwBYotA=; b=V36QEEiBoY7tk/thGw2WCfo/70G7em9yT7CDPAa6yeYO0RUhti9o05Hdu4HOTYIxPJ fKCTCww4TrvzU5c4CTivy/MkjEZ/R+Y5LNlGlAjuYcTiKZYJdpwaPpx5BWaxpxE3zjg3 kjrlavMMZLuybUIaPPkxTcHNrzufR4YBD3yZxgFDiJp2LDeTCcHckG4bujQWjZYnkRaj WjNp93jTejshXEOgeQXkV7rY2DUxm6vLWdevcFwu3wmMsBHWuFGxbW0SZCNo8F/lo2Zv 2kZWLgznVQMSHvzen/rJDwPGKbwYKab8hPOjkj+v40Bv03G37a1td7gUBSGlsI42Kmtp p3+w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766531531; x=1767136331; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=xEi01BqSTkmwBMdWxitsf6rmzRbefuQ2j6agJwBYotA=; b=nAzksaU+dN9vrdwHyEaFFhLDb0Mwrp6b1y1ASzQQY/VAmEfj4vjIuqCMa/z9VTCfV3 OqlTcaFi1/2iIwKb1+DYy6BKY3vWrARQNyx2gI0gBZ47wTI+/ug317VxzRITpsRVN3jF V2wKPtQGX+KoHegE2Dqc9DBzpcLXlX/m43Rw+SzB8RRi36NG1f39aWN0YTCxilozvh6v AtCYa59kT20wRiCGVQaf+vERMCzMGq/gPihJCtA/vsdy3qhx1fjUCLh0TXyzdRbxicqQ z209lUI5v1wk3OO/jBUx9hKEjJjs2EJ6VxnqYNxYK/L47e28vWBTRkppkl9Qc2N87z7c xXOA== X-Forwarded-Encrypted: i=1; AJvYcCU0gRrm688A3bwmxnNn9p1JWEePAaEAAREOtPxmsn4PaU464WH1dU0nnP5UzxPDfUxPiHps7qWFgR3UrIo=@vger.kernel.org X-Gm-Message-State: AOJu0YyOwwlEMUuooBEd6U2ImMvuifQuofJBnwpCBSGts0Q60RRHb0+W QGKFJ6UOZQx6LwCWIbSXLdjPuvtmK0Fu3vnf1LC0fxB7pjOPoTO20+Ib7ZHO750eBaaJHk8/NYq 9YSsBsg== X-Google-Smtp-Source: AGHT+IFXcGtLUkuoP4M1YIbs/KeL/27Ptmb6aknnvIFt/3xOqhSdSzHhf/AZm5q9iF2IB/zLgoBWxm0Dtnw= X-Received: from pfht19.prod.google.com ([2002:a62:ea13:0:b0:7f0:64eb:f9fe]) (user=seanjc job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6a20:7349:b0:366:19a5:b492 with SMTP id adf61e73a8af0-376a75ef489mr13858452637.5.1766531530759; Tue, 23 Dec 2025 15:12:10 -0800 (PST) Date: Tue, 23 Dec 2025 15:12:09 -0800 In-Reply-To: <20251127013440.3324671-11-yosry.ahmed@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20251127013440.3324671-1-yosry.ahmed@linux.dev> <20251127013440.3324671-11-yosry.ahmed@linux.dev> Message-ID: Subject: Re: [PATCH v3 10/16] KVM: selftests: Reuse virt mapping functions for nested EPTs From: Sean Christopherson To: Yosry Ahmed Cc: Paolo Bonzini , kvm@vger.kernel.org, linux-kernel@vger.kernel.org Content-Type: text/plain; charset="us-ascii" On Thu, Nov 27, 2025, Yosry Ahmed wrote: > __tdp_pg_map() bears a lot of resemblence to __virt_pg_map(). The > main differences are: > - It uses the EPT struct overlay instead of the PTE masks. > - It always assumes 4-level EPTs. > > To reuse __virt_pg_map(), initialize the PTE masks in nested MMU with > EPT PTE masks. EPTs have no 'present' or 'user' bits, so use the > 'readable' bit instead like shadow_{present/user}_mask, ignoring the > fact that entries can be present and not readable if the CPU has > VMX_EPT_EXECUTE_ONLY_BIT. This is simple and sufficient for testing. Ugh, no. I am strongly against playing the same insane games KVM itself plays with overloading protectin/access bits. There's no reason for selftests to do the same, e.g. selftests aren't shadowing guest PTEs and doing permission checks in hot paths and so don't need to multiplex a bunch of things into an inscrutable (but performant!) system. > Add an executable bitmask and update __virt_pg_map() and friends to set > the bit on newly created entries to match the EPT behavior. It's a nop > for x86 page tables. > > Another benefit of reusing the code is having separate handling for > upper-level PTEs vs 4K PTEs, which avoids some quirks like setting the > large bit on a 4K PTE in the EPTs. > > No functional change intended. > > Suggested-by: Sean Christopherson > Signed-off-by: Yosry Ahmed > --- > .../selftests/kvm/include/x86/processor.h | 3 + > .../testing/selftests/kvm/lib/x86/processor.c | 12 +- > tools/testing/selftests/kvm/lib/x86/vmx.c | 115 ++++-------------- > 3 files changed, 33 insertions(+), 97 deletions(-) > > diff --git a/tools/testing/selftests/kvm/include/x86/processor.h b/tools/testing/selftests/kvm/include/x86/processor.h > index fb2b2e53d453..62e10b296719 100644 > --- a/tools/testing/selftests/kvm/include/x86/processor.h > +++ b/tools/testing/selftests/kvm/include/x86/processor.h > @@ -1447,6 +1447,7 @@ struct pte_masks { > uint64_t dirty; > uint64_t huge; > uint64_t nx; > + uint64_t x; To be consistent with e.g. writable, call this executable. > uint64_t c; > uint64_t s; > }; > @@ -1464,6 +1465,7 @@ struct kvm_mmu { > #define PTE_DIRTY_MASK(mmu) ((mmu)->pte_masks.dirty) > #define PTE_HUGE_MASK(mmu) ((mmu)->pte_masks.huge) > #define PTE_NX_MASK(mmu) ((mmu)->pte_masks.nx) > +#define PTE_X_MASK(mmu) ((mmu)->pte_masks.x) > #define PTE_C_MASK(mmu) ((mmu)->pte_masks.c) > #define PTE_S_MASK(mmu) ((mmu)->pte_masks.s) > > @@ -1474,6 +1476,7 @@ struct kvm_mmu { > #define pte_dirty(mmu, pte) (!!(*(pte) & PTE_DIRTY_MASK(mmu))) > #define pte_huge(mmu, pte) (!!(*(pte) & PTE_HUGE_MASK(mmu))) > #define pte_nx(mmu, pte) (!!(*(pte) & PTE_NX_MASK(mmu))) > +#define pte_x(mmu, pte) (!!(*(pte) & PTE_X_MASK(mmu))) And then here to not assume PRESENT == READABLE, just check if the MMU even has a PRESENT bit. We may still need changes, e.g. the page table builders actually need to verify a PTE is _writable_, not just present, but that's largely an orthogonal issue. #define is_present_pte(mmu, pte) \ (PTE_PRESENT_MASK(mmu) ? \ !!(*(pte) & PTE_PRESENT_MASK(mmu)) : \ !!(*(pte) & (PTE_READABLE_MASK(mmu) | PTE_EXECUTABLE_MASK(mmu)))) And to properly capture the relationship between NX and EXECUTABLE: #define is_executable_pte(mmu, pte) \ ((*(pte) & (PTE_EXECUTABLE_MASK(mmu) | PTE_NX_MASK(mmu))) == PTE_EXECUTABLE_MASK(mmu)) #define is_nx_pte(mmu, pte) (!is_executable_pte(mmu, pte)) > #define pte_c(mmu, pte) (!!(*(pte) & PTE_C_MASK(mmu))) > #define pte_s(mmu, pte) (!!(*(pte) & PTE_S_MASK(mmu))) > > diff --git a/tools/testing/selftests/kvm/lib/x86/processor.c b/tools/testing/selftests/kvm/lib/x86/processor.c > index bff75ff05364..8b0e17f8ca37 100644 > --- a/tools/testing/selftests/kvm/lib/x86/processor.c > +++ b/tools/testing/selftests/kvm/lib/x86/processor.c > @@ -162,8 +162,7 @@ struct kvm_mmu *mmu_create(struct kvm_vm *vm, int pgtable_levels, > struct kvm_mmu *mmu = calloc(1, sizeof(*mmu)); > > TEST_ASSERT(mmu, "-ENOMEM when allocating MMU"); > - if (pte_masks) > - mmu->pte_masks = *pte_masks; > + mmu->pte_masks = *pte_masks; Rather than pass NULL (and allow NULL here) in the previous patch, pass an empty pte_masks. That avoids churning the MMU initialization code, and allows for a better TODO in the previous patch. > + /* > + * EPTs do not have 'present' or 'user' bits, instead bit 0 is the > + * 'readable' bit. In some cases, EPTs can be execute-only and an entry > + * is present but not readable. However, for the purposes of testing we > + * assume 'present' == 'user' == 'readable' for simplicity. > + */ > + pte_masks = (struct pte_masks){ > + .present = BIT_ULL(0), > + .user = BIT_ULL(0), > + .writable = BIT_ULL(1), > + .x = BIT_ULL(2), > + .accessed = BIT_ULL(5), > + .dirty = BIT_ULL(6), > + .huge = BIT_ULL(7), > + .nx = 0, > + }; > + > /* EPTP_PWL_4 is always used */ Make this a TODO, e.g. /* TODO: Add support for 5-level paging. */ so that it's clear this is a shortcoming, not some fundamental property of selftests.