From: Julien Grall <julien.grall@linaro.org>
To: Sergej Proskurin <proskurin@sec.in.tum.de>,
xen-devel@lists.xenproject.org
Cc: Julien Grall <julien.grall@arm.com>,
Stefano Stabellini <sstabellini@kernel.org>
Subject: Re: [PATCH v4 07/39] arm/p2m: Move hostp2m init/teardown to individual functions
Date: Mon, 9 Oct 2017 18:15:52 +0100 [thread overview]
Message-ID: <53e1b7e6-f0a0-9d5c-8f83-9a44fb0c1360@linaro.org> (raw)
In-Reply-To: <20170830183258.14612-8-proskurin@sec.in.tum.de>
Hi Sergej,
On 30/08/17 19:32, Sergej Proskurin wrote:
> This commit pulls out generic init/teardown functionality out of
> "p2m_init" and "p2m_teardown" into "p2m_init_one", "p2m_teardown_one",
> and "p2m_flush_table" functions. This allows our future implementation
> to reuse existing code for the initialization/teardown of altp2m views.
You likely want to expand the commit message here to explain:
1) Why you export the functions
2) How come you split p2m_teardown is now also flushing the tables...
Very likely 2) should be a separate patch as it is an addition of the
code and not a split.
>
> Signed-off-by: Sergej Proskurin <proskurin@sec.in.tum.de>
> ---
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Julien Grall <julien.grall@arm.com>
> ---
> v2: Added the function p2m_flush_table to the previous version.
>
> v3: Removed struct vttbr.
>
> Moved define INVALID_VTTBR to p2m.h.
>
> Exported function prototypes of "p2m_flush_table", "p2m_init_one",
> and "p2m_teardown_one" in p2m.h.
>
> Extended the function "p2m_flush_table" by additionally resetting
> the fields lowest_mapped_gfn and max_mapped_gfn.
>
> Added a "p2m_flush_tlb" call in "p2m_flush_table". On altp2m reset
> in function "altp2m_reset", it is important to flush the TLBs after
> clearing the root table pages and before clearing the intermediate
> altp2m page tables to prevent illegal access to stalled TLB entries
> on currently active VCPUs.
>
> Added a check checking whether p2m->root is NULL in p2m_flush_table.
>
> Renamed the function "p2m_free_one" to "p2m_teardown_one".
>
> Removed resetting p2m->vttbr in "p2m_teardown_one", as it the p2m
> will be destroyed afterwards.
>
> Moved call to "p2m_alloc_table" back to "p2m_init_one".
>
> Moved the introduction of the type p2m_class_t out of this patch.
>
> Moved the backpointer to the struct domain out of the struct
> p2m_domain.
>
> v4: Replaced the former use of clear_and_clean_page in p2m_flush_table
> by a routine that invalidates every p2m entry atomically. This
> avoids inconsistencies on CPUs that continue to use the views that
> are to be flushed (e.g., see altp2m_reset).
>
> Removed unnecessary initializations in the functions "p2m_init_one"
> and "p2m_teardown_one".
>
> Removed the define INVALID_VTTBR as it is not used any more.
>
> Cosmetic fixes.
> ---
> xen/arch/arm/p2m.c | 74 +++++++++++++++++++++++++++++++++++++++++++----
> xen/include/asm-arm/p2m.h | 9 ++++++
> 2 files changed, 78 insertions(+), 5 deletions(-)
>
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 5e86368010..3a1a38e7af 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -1203,27 +1203,65 @@ static void p2m_free_vmid(struct domain *d)
> spin_unlock(&vmid_alloc_lock);
> }
>
> -void p2m_teardown(struct domain *d)
> +/* Reset this p2m table to be empty. */
> +void p2m_flush_table(struct p2m_domain *p2m)
> {
> - struct p2m_domain *p2m = p2m_get_hostp2m(d);
> struct page_info *pg;
> + unsigned int i, j;
> + lpae_t *table;
> +
> + if ( p2m->root )
> + {
> + /* Clear all concatenated root level pages. */
> + for ( i = 0; i < P2M_ROOT_PAGES; i++ )
> + {
> + table = __map_domain_page(p2m->root + i);
> +
> + for ( j = 0; j < LPAE_ENTRIES; j++ )
> + {
> + lpae_t *entry = table + j;
> +
> + /*
> + * Individual altp2m views can be flushed, whilst altp2m is
> + * active. To avoid inconsistencies on CPUs that continue to
> + * use the views to be flushed (e.g., see altp2m_reset), we
> + * must remove every p2m entry atomically.
When I read this comment, I wonder how this is safe to clear without any
locking? At least to prevent multiple instance to modify the P2M at the
same time. If you expect the caller to do it for you, then an
ASSERT(...) is necessary at the beginning of the function.
Likely you want this function do the locking.
Also that comment is more suitable on top of the for loop rather than here.
> + */
> + p2m_remove_pte(entry, p2m->clean_pte);
> + }
> + }
You still haven't address my comment regarding the overhead you
introduce whilst tearing down a P2M (e.g when the domain is destroyed).
> + }
> +
> + /*
> + * Flush TLBs before releasing remaining intermediate p2m page tables to
> + * prevent illegal access to stalled TLB entries.
> + */
> + p2m_flush_tlb(p2m);
Again, this is called by p2m_flush_table where the P2M may not have been
allocated because the initialization failed. So trying to flush TLB may
lead to a panic in Xen (the vttbr is invalid).
Furthermore we already flush the TLBs when creating the domain (see
p2m_alloc_table). So you add yet another overhead.
>
> + /* Free the rest of the trie pages back to the paging pool. */
> while ( (pg = page_list_remove_head(&p2m->pages)) )
> free_domheap_page(pg);
>
> + p2m->lowest_mapped_gfn = INVALID_GFN;
> + p2m->max_mapped_gfn = _gfn(0);
> +}
> +
> +void p2m_teardown_one(struct p2m_domain *p2m)
> +{
> + p2m_flush_table(p2m);
> +
> if ( p2m->root )
> free_domheap_pages(p2m->root, P2M_ROOT_ORDER);
>
> p2m->root = NULL;
>
> - p2m_free_vmid(d);
> + p2m_free_vmid(p2m->domain);
This is a bit odd to read given the VMID is per P2M. Likely you want
your patches #9 and #10 before this patch.
>
> radix_tree_destroy(&p2m->mem_access_settings, NULL);
> }
>
> -int p2m_init(struct domain *d)
> +int p2m_init_one(struct domain *d, struct p2m_domain *p2m)
> {
> - struct p2m_domain *p2m = p2m_get_hostp2m(d);
> int rc = 0;
> unsigned int cpu;
>
> @@ -1268,6 +1306,32 @@ int p2m_init(struct domain *d)
> return rc;
> }
>
> +static void p2m_teardown_hostp2m(struct domain *d)
> +{
> + struct p2m_domain *p2m = p2m_get_hostp2m(d);
> +
> + p2m_teardown_one(p2m);
> +}
> +
> +void p2m_teardown(struct domain *d)
> +{
> + p2m_teardown_hostp2m(d);
> +}
> +
> +static int p2m_init_hostp2m(struct domain *d)
> +{
> + struct p2m_domain *p2m = p2m_get_hostp2m(d);
> +
> + p2m->p2m_class = p2m_host;
> +
> + return p2m_init_one(d, p2m);
> +}
> +
> +int p2m_init(struct domain *d)
> +{
> + return p2m_init_hostp2m(d);
> +}
Please explain in the commit message why you need to introduce
p2m_init/p2m_teardown that just call p2m_init_one/p2m_teardown_hostp2m.
> +
> /*
> * The function will go through the p2m and remove page reference when it
> * is required. The mapping will be removed from the p2m.
> diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
> index 332d74f11c..9bb38e689a 100644
> --- a/xen/include/asm-arm/p2m.h
> +++ b/xen/include/asm-arm/p2m.h
> @@ -295,6 +295,15 @@ static inline int guest_physmap_add_page(struct domain *d,
>
> mfn_t gfn_to_mfn(struct domain *d, gfn_t gfn);
>
> +/* Flushes the page table held by the p2m. */
> +void p2m_flush_table(struct p2m_domain *p2m);
> +
> +/* Initialize the p2m structure. */
> +int p2m_init_one(struct domain *d, struct p2m_domain *p2m);
> +
> +/* Release resources held by the p2m structure. */
> +void p2m_teardown_one(struct p2m_domain *p2m);
> +
> /*
> * Populate-on-demand
> */
>
Cheers,
--
Julien Grall
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-10-09 17:16 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-30 18:32 [PATCH v4 00/39] arm/altp2m: Introducing altp2m to ARM Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 01/39] arm/p2m: Introduce p2m_(switch|restore)_vttbr_and_(g|s)et_flags Sergej Proskurin
2017-10-09 16:25 ` Julien Grall
2018-01-10 12:45 ` Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 02/39] arm/p2m: Add first altp2m HVMOP stubs Sergej Proskurin
2017-10-09 16:43 ` Julien Grall
2018-01-10 17:16 ` Sergej Proskurin
2018-01-10 17:20 ` Julien Grall
2017-08-30 18:32 ` [PATCH v4 03/39] arm/p2m: Add hvm_allow_(set|get)_param Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 04/39] arm/p2m: Add HVMOP_altp2m_get_domain_state Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 05/39] arm/p2m: Introduce p2m_is_(hostp2m|altp2m) Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 06/39] arm/p2m: Cosmetic fix - substitute _gfn(ULONG_MAX) for INVALID_GFN Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 07/39] arm/p2m: Move hostp2m init/teardown to individual functions Sergej Proskurin
2017-10-09 17:15 ` Julien Grall [this message]
2018-01-10 17:06 ` Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 08/39] arm/p2m: Cosmetic fix - function prototype of p2m_alloc_table Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 09/39] arm/p2m: Rename parameter in p2m_alloc_vmid Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 10/39] arm/p2m: Change func prototype and impl of p2m_(alloc|free)_vmid Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 11/39] altp2m: Move (MAX|INVALID)_ALTP2M to xen/p2m-common.h Sergej Proskurin
2017-08-31 8:04 ` Jan Beulich
2017-08-31 9:49 ` Sergej Proskurin
2017-08-31 10:19 ` Jan Beulich
2017-08-31 14:03 ` Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 12/39] arm/p2m: Add altp2m init/teardown routines Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 13/39] arm/p2m: Add altp2m table flushing routine Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 14/39] arm/p2m: Add HVMOP_altp2m_set_domain_state Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 15/39] arm/p2m: Add HVMOP_altp2m_create_p2m Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 16/39] arm/p2m: Add HVMOP_altp2m_destroy_p2m Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 17/39] arm/p2m: Add HVMOP_altp2m_switch_p2m Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 18/39] arm/p2m: Add p2m_get_active_p2m macro Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 19/39] arm/p2m: Make p2m_restore_state ready for altp2m Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 20/39] arm/p2m: Make get_page_from_gva " Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 21/39] arm/p2m: Cosmetic fix - __p2m_get_mem_access Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 22/39] arm/p2m: Make p2m_mem_access_check ready for altp2m Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 23/39] arm/p2m: Cosmetic fix - function prototypes Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 24/39] arm/p2m: Make p2m_put_l3_page ready for altp2m Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 25/39] arm/p2m: Modify reference count only if hostp2m active Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 26/39] arm/p2m: Add HVMOP_altp2m_set_mem_access Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 27/39] arm/p2m: Add altp2m_propagate_change Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 28/39] altp2m: Rename p2m_altp2m_check to altp2m_check Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 29/39] x86/altp2m: Move altp2m_check to altp2m.c Sergej Proskurin
2017-08-30 18:42 ` Razvan Cojocaru
2017-08-30 19:02 ` Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 30/39] arm/altp2m: Move altp2m_check to altp2m.h Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 31/39] arm/altp2m: Introduce altp2m_switch_vcpu_altp2m_by_id Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 32/39] arm/altp2m: Make altp2m_vcpu_idx ready for altp2m Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 33/39] arm/p2m: Add altp2m paging mechanism Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 34/39] arm/p2m: Add HVMOP_altp2m_change_gfn Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 35/39] arm/p2m: Adjust debug information to altp2m Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 36/39] altp2m: Document external-only use on ARM Sergej Proskurin
2017-09-01 15:32 ` Wei Liu
2017-08-30 18:32 ` [PATCH v4 37/39] altp2m: Allow activating altp2m on ARM domains Sergej Proskurin
2017-09-01 15:35 ` Wei Liu
2017-08-30 18:32 ` [PATCH v4 38/39] arm/xen-access: Extend xen-access for altp2m on ARM Sergej Proskurin
2017-08-30 18:32 ` [PATCH v4 39/39] arm/xen-access: Add test of xc_altp2m_change_gfn Sergej Proskurin
2017-08-30 18:52 ` Razvan Cojocaru
2017-08-30 19:07 ` Sergej Proskurin
2017-10-07 10:18 ` [PATCH v4 00/39] arm/altp2m: Introducing altp2m to ARM Sergej Proskurin
2017-10-07 10:29 ` Julien Grall
2017-10-07 10:54 ` Sergej Proskurin
2017-10-09 17:21 ` Julien Grall
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=53e1b7e6-f0a0-9d5c-8f83-9a44fb0c1360@linaro.org \
--to=julien.grall@linaro.org \
--cc=julien.grall@arm.com \
--cc=proskurin@sec.in.tum.de \
--cc=sstabellini@kernel.org \
--cc=xen-devel@lists.xenproject.org \
/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;
as well as URLs for NNTP newsgroup(s).