* [PATCH] x86/mm: Drop preemptible signal through {get, put}_page_type*()
@ 2018-08-28 15:35 Andrew Cooper
2018-08-28 16:07 ` Jan Beulich
0 siblings, 1 reply; 2+ messages in thread
From: Andrew Cooper @ 2018-08-28 15:35 UTC (permalink / raw)
To: Xen-devel; +Cc: Andrew Cooper, Wei Liu, Jan Beulich, Roger Pau Monné
After XSA-273, handling of L2 pagetables must strictly be preemptible, meaning
that all page types are now strictly preemptible (>= L2) or not (L1, SEGDESC).
Simplify the code by removing the preemptible booleans, which has an
unexpectedly large change to _get_page_type().
add/remove: 0/0 grow/shrink: 0/15 up/down: 0/-509 (-509)
Function old new delta
put_page_type 9 7 -2
get_page_type 24 22 -2
put_page_from_l2e 251 247 -4
put_page_type_preemptible 12 7 -5
put_page_from_l4e 268 263 -5
put_page_from_l3e 461 456 -5
get_page_type_preemptible 10 5 -5
put_page_from_l1e 385 377 -8
vcpu_destroy_pagetables 450 437 -13
put_old_guest_table 119 103 -16
get_page_from_l1e 1214 1196 -18
get_page_and_type_from_mfn 240 206 -34
_put_page_type 842 804 -38
do_mmuext_op 5576 5526 -50
_get_page_type 5771 5467 -304
Total: Before=3297078, After=3296569, chg -0.02%
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: Roger Pau Monné <roger.pau@citrix.com>
---
xen/arch/x86/domain.c | 2 +-
xen/arch/x86/mm.c | 76 ++++++++++++++++++++----------------------------
xen/include/asm-x86/mm.h | 3 +-
3 files changed, 34 insertions(+), 47 deletions(-)
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index eb1e93f..4f64602 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -1875,7 +1875,7 @@ static int relinquish_memory(
if ( likely(y == x) )
{
/* No need for atomic update of type_info here: noone else updates it. */
- switch ( ret = free_page_type(page, x, 1) )
+ switch ( ret = free_page_type(page, x) )
{
case 0:
break;
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 8ac4412..f2faaa8 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -613,12 +613,11 @@ static int alloc_segdesc_page(struct page_info *page)
return i == 512 ? 0 : -EINVAL;
}
-static int _get_page_type(struct page_info *page, unsigned long type,
- bool preemptible);
+static int _get_page_type(struct page_info *page, unsigned long type);
static int get_page_and_type_from_mfn(
mfn_t mfn, unsigned long type, struct domain *d,
- int partial, int preemptible)
+ int partial)
{
struct page_info *page = mfn_to_page(mfn);
int rc;
@@ -627,10 +626,10 @@ static int get_page_and_type_from_mfn(
unlikely(!get_page_from_mfn(mfn, d)) )
return -EINVAL;
- rc = _get_page_type(page, type, preemptible);
+ rc = _get_page_type(page, type);
if ( unlikely(rc) && partial >= 0 &&
- (!preemptible || page != current->arch.old_guest_table) )
+ page != current->arch.old_guest_table )
put_page(page);
return rc;
@@ -1125,7 +1124,7 @@ get_page_from_l2e(
return -EINVAL;
}
- rc = get_page_and_type_from_mfn(_mfn(mfn), PGT_l1_page_table, d, 0, 0);
+ rc = get_page_and_type_from_mfn(_mfn(mfn), PGT_l1_page_table, d, 0);
if ( unlikely(rc == -EINVAL) && get_l2_linear_pagetable(l2e, pfn, d) )
rc = 0;
@@ -1157,7 +1156,7 @@ get_page_from_l3e(
}
rc = get_page_and_type_from_mfn(
- l3e_get_mfn(l3e), PGT_l2_page_table, d, partial, 1);
+ l3e_get_mfn(l3e), PGT_l2_page_table, d, partial);
if ( unlikely(rc == -EINVAL) &&
!is_pv_32bit_domain(d) &&
get_l3_linear_pagetable(l3e, pfn, d) )
@@ -1190,15 +1189,14 @@ get_page_from_l4e(
}
rc = get_page_and_type_from_mfn(
- l4e_get_mfn(l4e), PGT_l3_page_table, d, partial, 1);
+ l4e_get_mfn(l4e), PGT_l3_page_table, d, partial);
if ( unlikely(rc == -EINVAL) && get_l4_linear_pagetable(l4e, pfn, d) )
rc = 0;
return rc;
}
-static int _put_page_type(struct page_info *page, bool preemptible,
- struct page_info *ptpg);
+static int _put_page_type(struct page_info *page, struct page_info *ptpg);
void put_page_from_l1e(l1_pgentry_t l1e, struct domain *l1e_owner)
{
@@ -1295,7 +1293,7 @@ static int put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn)
else
{
struct page_info *pg = l2e_get_page(l2e);
- int rc = _put_page_type(pg, false, mfn_to_page(_mfn(pfn)));
+ int rc = _put_page_type(pg, mfn_to_page(_mfn(pfn)));
ASSERT(!rc);
put_page(pg);
@@ -1331,7 +1329,7 @@ static int put_page_from_l3e(l3_pgentry_t l3e, unsigned long pfn,
if ( unlikely(partial > 0) )
{
ASSERT(!defer);
- return _put_page_type(pg, true, mfn_to_page(_mfn(pfn)));
+ return _put_page_type(pg, mfn_to_page(_mfn(pfn)));
}
if ( defer )
@@ -1341,7 +1339,7 @@ static int put_page_from_l3e(l3_pgentry_t l3e, unsigned long pfn,
return 0;
}
- rc = _put_page_type(pg, true, mfn_to_page(_mfn(pfn)));
+ rc = _put_page_type(pg, mfn_to_page(_mfn(pfn)));
if ( likely(!rc) )
put_page(pg);
@@ -1361,7 +1359,7 @@ static int put_page_from_l4e(l4_pgentry_t l4e, unsigned long pfn,
if ( unlikely(partial > 0) )
{
ASSERT(!defer);
- return _put_page_type(pg, true, mfn_to_page(_mfn(pfn)));
+ return _put_page_type(pg, mfn_to_page(_mfn(pfn)));
}
if ( defer )
@@ -1371,7 +1369,7 @@ static int put_page_from_l4e(l4_pgentry_t l4e, unsigned long pfn,
return 0;
}
- rc = _put_page_type(pg, true, mfn_to_page(_mfn(pfn)));
+ rc = _put_page_type(pg, mfn_to_page(_mfn(pfn)));
if ( likely(!rc) )
put_page(pg);
}
@@ -1544,7 +1542,7 @@ static int alloc_l3_table(struct page_info *page)
else
rc = get_page_and_type_from_mfn(
l3e_get_mfn(pl3e[i]),
- PGT_l2_page_table | PGT_pae_xen_l2, d, partial, 1);
+ PGT_l2_page_table | PGT_pae_xen_l2, d, partial);
}
else if ( (rc = get_page_from_l3e(pl3e[i], pfn, d, partial)) > 0 )
continue;
@@ -2378,8 +2376,7 @@ static void get_page_light(struct page_info *page)
while ( unlikely(y != x) );
}
-static int alloc_page_type(struct page_info *page, unsigned long type,
- int preemptible)
+static int alloc_page_type(struct page_info *page, unsigned long type)
{
struct domain *owner = page_get_owner(page);
int rc;
@@ -2394,15 +2391,12 @@ static int alloc_page_type(struct page_info *page, unsigned long type,
rc = alloc_l1_table(page);
break;
case PGT_l2_page_table:
- ASSERT(preemptible);
rc = alloc_l2_table(page, type);
break;
case PGT_l3_page_table:
- ASSERT(preemptible);
rc = alloc_l3_table(page);
break;
case PGT_l4_page_table:
- ASSERT(preemptible);
rc = alloc_l4_table(page);
break;
case PGT_seg_desc_page:
@@ -2453,8 +2447,7 @@ static int alloc_page_type(struct page_info *page, unsigned long type,
}
-int free_page_type(struct page_info *page, unsigned long type,
- int preemptible)
+int free_page_type(struct page_info *page, unsigned long type)
{
struct domain *owner = page_get_owner(page);
unsigned long gmfn;
@@ -2485,15 +2478,12 @@ int free_page_type(struct page_info *page, unsigned long type,
rc = 0;
break;
case PGT_l2_page_table:
- ASSERT(preemptible);
rc = free_l2_table(page);
break;
case PGT_l3_page_table:
- ASSERT(preemptible);
rc = free_l3_table(page);
break;
case PGT_l4_page_table:
- ASSERT(preemptible);
rc = free_l4_table(page);
break;
default:
@@ -2508,9 +2498,9 @@ int free_page_type(struct page_info *page, unsigned long type,
static int _put_final_page_type(struct page_info *page, unsigned long type,
- bool preemptible, struct page_info *ptpg)
+ struct page_info *ptpg)
{
- int rc = free_page_type(page, type, preemptible);
+ int rc = free_page_type(page, type);
/* No need for atomic update of type_info here: noone else updates it. */
if ( rc == 0 )
@@ -2544,8 +2534,7 @@ static int _put_final_page_type(struct page_info *page, unsigned long type,
}
-static int _put_page_type(struct page_info *page, bool preemptible,
- struct page_info *ptpg)
+static int _put_page_type(struct page_info *page, struct page_info *ptpg)
{
unsigned long nx, x, y = page->u.inuse.type_info;
@@ -2576,7 +2565,7 @@ static int _put_page_type(struct page_info *page, bool preemptible,
x, nx)) != x) )
break;
/* We cleared the 'valid bit' so we do the clean up. */
- rc = _put_final_page_type(page, x, preemptible, ptpg);
+ rc = _put_final_page_type(page, x, ptpg);
if ( x & PGT_partial )
put_page(page);
@@ -2624,14 +2613,13 @@ static int _put_page_type(struct page_info *page, bool preemptible,
break;
}
- if ( preemptible && hypercall_preempt_check() )
+ if ( hypercall_preempt_check() )
return -EINTR;
}
}
-static int _get_page_type(struct page_info *page, unsigned long type,
- bool preemptible)
+static int _get_page_type(struct page_info *page, unsigned long type)
{
unsigned long nx, x, y = page->u.inuse.type_info;
int rc = 0, iommu_ret = 0;
@@ -2728,7 +2716,7 @@ static int _get_page_type(struct page_info *page, unsigned long type,
{
/* Someone else is updating validation of this page. Wait... */
do {
- if ( preemptible && hypercall_preempt_check() )
+ if ( hypercall_preempt_check() )
return -EINTR;
cpu_relax();
} while ( (y = page->u.inuse.type_info) == x );
@@ -2742,7 +2730,7 @@ static int _get_page_type(struct page_info *page, unsigned long type,
if ( likely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) == x) )
break;
- if ( preemptible && hypercall_preempt_check() )
+ if ( hypercall_preempt_check() )
return -EINTR;
}
@@ -2771,7 +2759,7 @@ static int _get_page_type(struct page_info *page, unsigned long type,
page->partial_pte = 0;
}
page->linear_pt_count = 0;
- rc = alloc_page_type(page, type, preemptible);
+ rc = alloc_page_type(page, type);
}
if ( (x & PGT_partial) && !(nx & PGT_partial) )
@@ -2785,14 +2773,14 @@ static int _get_page_type(struct page_info *page, unsigned long type,
void put_page_type(struct page_info *page)
{
- int rc = _put_page_type(page, false, NULL);
+ int rc = _put_page_type(page, NULL);
ASSERT(rc == 0);
(void)rc;
}
int get_page_type(struct page_info *page, unsigned long type)
{
- int rc = _get_page_type(page, type, false);
+ int rc = _get_page_type(page, type);
if ( likely(rc == 0) )
return 1;
@@ -2802,14 +2790,14 @@ int get_page_type(struct page_info *page, unsigned long type)
int put_page_type_preemptible(struct page_info *page)
{
- return _put_page_type(page, true, NULL);
+ return _put_page_type(page, NULL);
}
int get_page_type_preemptible(struct page_info *page, unsigned long type)
{
ASSERT(!current->arch.old_guest_table);
- return _get_page_type(page, type, true);
+ return _get_page_type(page, type);
}
int put_old_guest_table(struct vcpu *v)
@@ -2819,7 +2807,7 @@ int put_old_guest_table(struct vcpu *v)
if ( !v->arch.old_guest_table )
return 0;
- switch ( rc = _put_page_type(v->arch.old_guest_table, true,
+ switch ( rc = _put_page_type(v->arch.old_guest_table,
v->arch.old_guest_ptpg) )
{
case -EINTR:
@@ -2945,7 +2933,7 @@ int new_guest_cr3(mfn_t mfn)
return 0;
}
- rc = get_page_and_type_from_mfn(mfn, PGT_root_page_table, d, 0, 1);
+ rc = get_page_and_type_from_mfn(mfn, PGT_root_page_table, d, 0);
switch ( rc )
{
case 0:
@@ -3333,7 +3321,7 @@ long do_mmuext_op(
if ( op.arg1.mfn != 0 )
{
rc = get_page_and_type_from_mfn(
- _mfn(op.arg1.mfn), PGT_root_page_table, currd, 0, 1);
+ _mfn(op.arg1.mfn), PGT_root_page_table, currd, 0);
if ( unlikely(rc) )
{
diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h
index 6e45651..1988e57 100644
--- a/xen/include/asm-x86/mm.h
+++ b/xen/include/asm-x86/mm.h
@@ -330,8 +330,7 @@ static inline void *__page_to_virt(const struct page_info *pg)
(PAGE_SIZE / (sizeof(*pg) & -sizeof(*pg))));
}
-int free_page_type(struct page_info *page, unsigned long type,
- int preemptible);
+int free_page_type(struct page_info *page, unsigned long type);
void init_xen_pae_l2_slots(l2_pgentry_t *l2t, const struct domain *d);
void init_xen_l4_slots(l4_pgentry_t *l4t, mfn_t l4mfn,
--
2.1.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] x86/mm: Drop preemptible signal through {get, put}_page_type*()
2018-08-28 15:35 [PATCH] x86/mm: Drop preemptible signal through {get, put}_page_type*() Andrew Cooper
@ 2018-08-28 16:07 ` Jan Beulich
0 siblings, 0 replies; 2+ messages in thread
From: Jan Beulich @ 2018-08-28 16:07 UTC (permalink / raw)
To: Andrew Cooper; +Cc: Xen-devel, Wei Liu, Roger Pau Monne
>>> On 28.08.18 at 17:35, <andrew.cooper3@citrix.com> wrote:
> @@ -627,10 +626,10 @@ static int get_page_and_type_from_mfn(
> unlikely(!get_page_from_mfn(mfn, d)) )
> return -EINVAL;
>
> - rc = _get_page_type(page, type, preemptible);
> + rc = _get_page_type(page, type);
>
> if ( unlikely(rc) && partial >= 0 &&
> - (!preemptible || page != current->arch.old_guest_table) )
> + page != current->arch.old_guest_table )
> put_page(page);
If preemptibility is now tied to the type, how can this part of the
condition go away altogether here? At least I didn't understand
the description to mean everything is meant to become
preemptible.
Same elsewhere. Please clarify.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-08-28 16:07 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-28 15:35 [PATCH] x86/mm: Drop preemptible signal through {get, put}_page_type*() Andrew Cooper
2018-08-28 16:07 ` Jan Beulich
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.