|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [RFC 03/16] xen/arm: Allow lpae_is_{table, mapping} helpers to work on invalid entry
On Mon, 8 Oct 2018, Julien Grall wrote:
> Currently, lpae_is_{table, mapping} helpers will always return false on
> entries with the valid bit unset. However, it would be useful to have them
> operating on any entry. For instance to store information in advance but
> still request a fault.
>
> With that change, the p2m is now providing an overlay for *_is_{table,
> mapping} that will check the valid bit of the entry.
>
> Signed-off-by: Julien Grall <julien.grall@xxxxxxx>
Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
> ---
>
> The patch was previously sent separately.
> ---
> xen/arch/arm/guest_walk.c | 2 +-
> xen/arch/arm/mm.c | 2 +-
> xen/arch/arm/p2m.c | 22 ++++++++++++++++++----
> xen/include/asm-arm/lpae.h | 11 +++++++----
> 4 files changed, 27 insertions(+), 10 deletions(-)
>
> diff --git a/xen/arch/arm/guest_walk.c b/xen/arch/arm/guest_walk.c
> index e3e21bdad3..4a1b4cf2c8 100644
> --- a/xen/arch/arm/guest_walk.c
> +++ b/xen/arch/arm/guest_walk.c
> @@ -566,7 +566,7 @@ static int guest_walk_ld(const struct vcpu *v,
> * PTE is invalid or holds a reserved entry (PTE<1:0> == x0)) or if the
> PTE
> * maps a memory block at level 3 (PTE<1:0> == 01).
> */
> - if ( !lpae_is_mapping(pte, level) )
> + if ( !lpae_is_valid(pte) || !lpae_is_mapping(pte, level) )
> return -EFAULT;
>
> /* Make sure that the lower bits of the PTE's base address are zero. */
> diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
> index 0bc31b1d9b..987fcb9162 100644
> --- a/xen/arch/arm/mm.c
> +++ b/xen/arch/arm/mm.c
> @@ -996,7 +996,7 @@ static int create_xen_entries(enum xenmap_operation op,
> for(; addr < addr_end; addr += PAGE_SIZE, mfn = mfn_add(mfn, 1))
> {
> entry = &xen_second[second_linear_offset(addr)];
> - if ( !lpae_is_table(*entry, 2) )
> + if ( !lpae_is_valid(*entry) || !lpae_is_table(*entry, 2) )
> {
> rc = create_xen_table(entry);
> if ( rc < 0 ) {
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index f8a2f6459e..8fffb42889 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -219,6 +219,20 @@ static p2m_access_t p2m_mem_access_radix_get(struct
> p2m_domain *p2m, gfn_t gfn)
> return radix_tree_ptr_to_int(ptr);
> }
>
> +/*
> + * lpae_is_* helpers don't check whether the valid bit is set in the
> + * PTE. Provide our own overlay to check the valid bit.
> + */
> +static inline bool p2m_is_mapping(lpae_t pte, unsigned int level)
> +{
> + return lpae_is_valid(pte) && lpae_is_mapping(pte, level);
> +}
> +
> +static inline bool p2m_is_superpage(lpae_t pte, unsigned int level)
> +{
> + return lpae_is_valid(pte) && lpae_is_superpage(pte, level);
> +}
> +
> #define GUEST_TABLE_MAP_FAILED 0
> #define GUEST_TABLE_SUPER_PAGE 1
> #define GUEST_TABLE_NORMAL_PAGE 2
> @@ -262,7 +276,7 @@ static int p2m_next_level(struct p2m_domain *p2m, bool
> read_only,
>
> /* The function p2m_next_level is never called at the 3rd level */
> ASSERT(level < 3);
> - if ( lpae_is_mapping(*entry, level) )
> + if ( p2m_is_mapping(*entry, level) )
> return GUEST_TABLE_SUPER_PAGE;
>
> mfn = lpae_get_mfn(*entry);
> @@ -642,7 +656,7 @@ static void p2m_free_entry(struct p2m_domain *p2m,
> return;
>
> /* Nothing to do but updating the stats if the entry is a super-page. */
> - if ( lpae_is_superpage(entry, level) )
> + if ( p2m_is_superpage(entry, level) )
> {
> p2m->stats.mappings[level]--;
> return;
> @@ -697,7 +711,7 @@ static bool p2m_split_superpage(struct p2m_domain *p2m,
> lpae_t *entry,
> * a superpage.
> */
> ASSERT(level < target);
> - ASSERT(lpae_is_superpage(*entry, level));
> + ASSERT(p2m_is_superpage(*entry, level));
>
> page = alloc_domheap_page(NULL, 0);
> if ( !page )
> @@ -836,7 +850,7 @@ static int __p2m_set_entry(struct p2m_domain *p2m,
> /* We need to split the original page. */
> lpae_t split_pte = *entry;
>
> - ASSERT(lpae_is_superpage(*entry, level));
> + ASSERT(p2m_is_superpage(*entry, level));
>
> if ( !p2m_split_superpage(p2m, &split_pte, level, target, offsets) )
> {
> diff --git a/xen/include/asm-arm/lpae.h b/xen/include/asm-arm/lpae.h
> index 17fdc6074f..545b0c8f24 100644
> --- a/xen/include/asm-arm/lpae.h
> +++ b/xen/include/asm-arm/lpae.h
> @@ -133,16 +133,19 @@ static inline bool lpae_is_valid(lpae_t pte)
> return pte.walk.valid;
> }
>
> +/*
> + * lpae_is_* don't check the valid bit. This gives an opportunity for the
> + * callers to operate on the entry even if they are not valid. For
> + * instance to store information in advance.
> + */
> static inline bool lpae_is_table(lpae_t pte, unsigned int level)
> {
> - return (level < 3) && lpae_is_valid(pte) && pte.walk.table;
> + return (level < 3) && pte.walk.table;
> }
>
> static inline bool lpae_is_mapping(lpae_t pte, unsigned int level)
> {
> - if ( !lpae_is_valid(pte) )
> - return false;
> - else if ( level == 3 )
> + if ( level == 3 )
> return pte.walk.table;
> else
> return !pte.walk.table;
> --
> 2.11.0
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |