Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:FrontRunner
xen.11173
5c7e70e2-x86-mm-L3-unvalidation-preemptible.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5c7e70e2-x86-mm-L3-unvalidation-preemptible.patch of Package xen.11173
# Commit bac4567a67d5e8b916801ea5a04cf8b443dfb245 # Date 2019-03-05 13:51:46 +0100 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> x86/mm: add explicit preemption checks to L3 (un)validation When recursive page tables are used at the L3 level, unvalidation of a single L4 table may incur unvalidation of two levels of L3 tables, i.e. a maximum iteration count of 512^3 for unvalidating an L4 table. The preemption check in free_l2_table() as well as the one in _put_page_type() may never be reached, so explicit checking is needed in free_l3_table(). When recursive page tables are used at the L4 level, the iteration count at L4 alone is capped at 512^2. As soon as a present L3 entry is hit which itself needs unvalidation (and hence requiring another nested loop with 512 iterations), the preemption checks added here kick in, so no further preemption checking is needed at L4 (until we decide to permit 5-level paging for PV guests). The validation side additions are done just for symmetry. This is part of XSA-290. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1612,6 +1612,13 @@ static int alloc_l3_table(struct page_in for ( i = page->nr_validated_ptes; i < L3_PAGETABLE_ENTRIES; i++, partial = 0 ) { + if ( i > page->nr_validated_ptes && hypercall_preempt_check() ) + { + page->nr_validated_ptes = i; + rc = -ERESTART; + break; + } + if ( is_pv_32bit_domain(d) && (i == 3) ) { if ( !(l3e_get_flags(pl3e[i]) & _PAGE_PRESENT) || @@ -1913,15 +1920,25 @@ static int free_l3_table(struct page_inf pl3e = map_domain_page(_mfn(pfn)); - do { + for ( ; ; ) + { rc = put_page_from_l3e(pl3e[i], pfn, partial, 0); if ( rc < 0 ) break; + partial = 0; - if ( rc > 0 ) - continue; - pl3e[i] = unadjust_guest_l3e(pl3e[i], d); - } while ( i-- ); + if ( rc == 0 ) + pl3e[i] = unadjust_guest_l3e(pl3e[i], d); + + if ( !i-- ) + break; + + if ( hypercall_preempt_check() ) + { + rc = -EINTR; + break; + } + } unmap_domain_page(pl3e);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor