[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] revert "x86/mm: re-implement get_page_light() using an atomic increment"
commit b819bd65f4fb25be582f66ba2e4134f61d86f459 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Tue Apr 30 08:37:19 2024 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Apr 30 08:37:19 2024 +0200 revert "x86/mm: re-implement get_page_light() using an atomic increment" This reverts commit c40bc0576dcc5acd4d7e22ef628eb4642f568533. That change aimed at eliminating an open-coded lock-like construct, which really isn't all that similar to, in particular, get_page(). The function always succeeds. Any remaining concern would want taking care of by placing block_lock_speculation() at the end of the function. Since the function is called only during page (de)validation, any possible performance concerns over such extra serialization could likely be addressed by pre-validating (e.g. via pinning) page tables. The fundamental issue with the change being reverted is that it detects bad state only after already having caused possible corruption. While the system is going to be halted in such an event, there is a time window during which the resulting incorrect state could be leveraged by a clever (in particular: fast enough) attacker. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Acked-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Acked-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- xen/arch/x86/mm.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 87529db7d1..d968bbbc73 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -2582,10 +2582,16 @@ bool get_page(struct page_info *page, const struct domain *domain) */ static void get_page_light(struct page_info *page) { - unsigned long old_pgc = arch_fetch_and_add(&page->count_info, 1); + unsigned long x, nx, y = page->count_info; - BUG_ON(!(old_pgc & PGC_count_mask)); /* Not allocated? */ - BUG_ON(!((old_pgc + 1) & PGC_count_mask)); /* Overflow? */ + do { + x = y; + nx = x + 1; + BUG_ON(!(x & PGC_count_mask)); /* Not allocated? */ + BUG_ON(!(nx & PGC_count_mask)); /* Overflow? */ + y = cmpxchg(&page->count_info, x, nx); + } + while ( unlikely(y != x) ); } static int validate_page(struct page_info *page, unsigned long type, -- generated by git-patchbot for /home/xen/git/xen.git#staging
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |