Message ID | 20241104133204.85208-2-qperret@google.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | KVM: arm64: Non-protected guest stage-2 support for pKVM | expand |
On Mon, Nov 04, 2024 at 01:31:47PM +0000, Quentin Perret wrote: Hi Quentin, > The 'concrete' (a.k.a non-meta) page states are currently encoded using > software bits in PTEs. For performance reasons, the abstract > pkvm_page_state enum uses the same bits to encode these states as that > makes conversions from and to PTEs easy. > > In order to prepare the ground for moving the 'concrete' state storage > to the hyp vmemmap, re-arrange the enum to use bits 0 and 1 for this > purpose. > > No functional changes intended. > > Signed-off-by: Quentin Perret <qperret@google.com> > --- > arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 17 ++++++++++------- > 1 file changed, 10 insertions(+), 7 deletions(-) > > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h > index 0972faccc2af..ca3177481b78 100644 > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h > @@ -24,25 +24,28 @@ > */ > enum pkvm_page_state { > PKVM_PAGE_OWNED = 0ULL, > - PKVM_PAGE_SHARED_OWNED = KVM_PGTABLE_PROT_SW0, > - PKVM_PAGE_SHARED_BORROWED = KVM_PGTABLE_PROT_SW1, > - __PKVM_PAGE_RESERVED = KVM_PGTABLE_PROT_SW0 | > - KVM_PGTABLE_PROT_SW1, > + PKVM_PAGE_SHARED_OWNED = BIT(0), > + PKVM_PAGE_SHARED_BORROWED = BIT(1), > + __PKVM_PAGE_RESERVED = BIT(0) | BIT(1), > > /* Meta-states which aren't encoded directly in the PTE's SW bits */ > - PKVM_NOPAGE, > + PKVM_NOPAGE = BIT(2), > }; I guess we will still have to keep around the software bit annotation for sharing MMIO regions from the host. This would not be tracked by the vmemmap but it will still be in the s2 pagetable. As this is tagged with no functional changes intended, are we safe because we are not supporting MMIO sharing currently ? > +#define PKVM_PAGE_META_STATES_MASK (~(BIT(0) | BIT(1))) > > #define PKVM_PAGE_STATE_PROT_MASK (KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1) > static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot, > enum pkvm_page_state state) > { > - return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state; > + BUG_ON(state & PKVM_PAGE_META_STATES_MASK); > + prot &= ~PKVM_PAGE_STATE_PROT_MASK; > + prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state); > + return prot; > } > > static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot) > { > - return prot & PKVM_PAGE_STATE_PROT_MASK; > + return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot); > } > Thanks, Sebastian > struct host_mmu { > -- > 2.47.0.163.g1226f6d8fa-goog >
Hi Seb, On Monday 04 Nov 2024 at 17:31:50 (+0000), Sebastian Ene wrote: > On Mon, Nov 04, 2024 at 01:31:47PM +0000, Quentin Perret wrote: > > Hi Quentin, > > > The 'concrete' (a.k.a non-meta) page states are currently encoded using > > software bits in PTEs. For performance reasons, the abstract > > pkvm_page_state enum uses the same bits to encode these states as that > > makes conversions from and to PTEs easy. > > > > In order to prepare the ground for moving the 'concrete' state storage > > to the hyp vmemmap, re-arrange the enum to use bits 0 and 1 for this > > purpose. > > > > No functional changes intended. > > > > Signed-off-by: Quentin Perret <qperret@google.com> > > --- > > arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 17 ++++++++++------- > > 1 file changed, 10 insertions(+), 7 deletions(-) > > > > diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h > > index 0972faccc2af..ca3177481b78 100644 > > --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h > > +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h > > @@ -24,25 +24,28 @@ > > */ > > enum pkvm_page_state { > > PKVM_PAGE_OWNED = 0ULL, > > - PKVM_PAGE_SHARED_OWNED = KVM_PGTABLE_PROT_SW0, > > - PKVM_PAGE_SHARED_BORROWED = KVM_PGTABLE_PROT_SW1, > > - __PKVM_PAGE_RESERVED = KVM_PGTABLE_PROT_SW0 | > > - KVM_PGTABLE_PROT_SW1, > > + PKVM_PAGE_SHARED_OWNED = BIT(0), > > + PKVM_PAGE_SHARED_BORROWED = BIT(1), > > + __PKVM_PAGE_RESERVED = BIT(0) | BIT(1), > > > > /* Meta-states which aren't encoded directly in the PTE's SW bits */ > > - PKVM_NOPAGE, > > + PKVM_NOPAGE = BIT(2), > > }; > > I guess we will still have to keep around the software bit annotation > for sharing MMIO regions from the host. This would not be tracked by the > vmemmap but it will still be in the s2 pagetable. As this is tagged with no > functional changes intended, are we safe because we are not supporting > MMIO sharing currently ? That's right, currently no MMIO sharing is allowed -- see how host_get_page_state() returns PKVM_NOPAGE for non-memory addresses, so we should be good! Sharing/donating devices is absolutely going to be needed eventually, but I hoped we could make that a separate series. And yes, we'll need _some_ data-structure at EL2 to track that, possibly the page-table, but could also be something else similar to how this series moves that away from the pgt for memory. Hopefully that's an orthogonal discussion we can have later :-) Thanks, Quentin
diff --git a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h index 0972faccc2af..ca3177481b78 100644 --- a/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h +++ b/arch/arm64/kvm/hyp/include/nvhe/mem_protect.h @@ -24,25 +24,28 @@ */ enum pkvm_page_state { PKVM_PAGE_OWNED = 0ULL, - PKVM_PAGE_SHARED_OWNED = KVM_PGTABLE_PROT_SW0, - PKVM_PAGE_SHARED_BORROWED = KVM_PGTABLE_PROT_SW1, - __PKVM_PAGE_RESERVED = KVM_PGTABLE_PROT_SW0 | - KVM_PGTABLE_PROT_SW1, + PKVM_PAGE_SHARED_OWNED = BIT(0), + PKVM_PAGE_SHARED_BORROWED = BIT(1), + __PKVM_PAGE_RESERVED = BIT(0) | BIT(1), /* Meta-states which aren't encoded directly in the PTE's SW bits */ - PKVM_NOPAGE, + PKVM_NOPAGE = BIT(2), }; +#define PKVM_PAGE_META_STATES_MASK (~(BIT(0) | BIT(1))) #define PKVM_PAGE_STATE_PROT_MASK (KVM_PGTABLE_PROT_SW0 | KVM_PGTABLE_PROT_SW1) static inline enum kvm_pgtable_prot pkvm_mkstate(enum kvm_pgtable_prot prot, enum pkvm_page_state state) { - return (prot & ~PKVM_PAGE_STATE_PROT_MASK) | state; + BUG_ON(state & PKVM_PAGE_META_STATES_MASK); + prot &= ~PKVM_PAGE_STATE_PROT_MASK; + prot |= FIELD_PREP(PKVM_PAGE_STATE_PROT_MASK, state); + return prot; } static inline enum pkvm_page_state pkvm_getstate(enum kvm_pgtable_prot prot) { - return prot & PKVM_PAGE_STATE_PROT_MASK; + return FIELD_GET(PKVM_PAGE_STATE_PROT_MASK, prot); } struct host_mmu {
The 'concrete' (a.k.a non-meta) page states are currently encoded using software bits in PTEs. For performance reasons, the abstract pkvm_page_state enum uses the same bits to encode these states as that makes conversions from and to PTEs easy. In order to prepare the ground for moving the 'concrete' state storage to the hyp vmemmap, re-arrange the enum to use bits 0 and 1 for this purpose. No functional changes intended. Signed-off-by: Quentin Perret <qperret@google.com> --- arch/arm64/kvm/hyp/include/nvhe/mem_protect.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)