Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
xen.5015
xsa218-1.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xsa218-1.patch of Package xen.5015
From: Jan Beulich <jbeulich@suse.com> Subject: gnttab: fix unmap pin accounting race Once all {writable} mappings of a grant entry have been unmapped, the hypervisor informs the guest that the grant entry has been released by clearing the _GTF_{reading,writing} usage flags in the guest's grant table as appropriate. Unfortunately, at the moment, the code that updates the accounting happens in a different critical section than the one which updates the usage flags; this means that under the right circumstances, there may be a window in time after the hypervisor reported the grant as being free during which the grant referee still had access to the page. Move the grant accounting code into the same critical section as the reporting code to make sure this kind of race can't happen. This is part of XSA-218. Reported-by: Jann Horn <jannh@google.com> Signed-off-by: Jan Beulich <jbeulich@suse.com> --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -905,15 +905,8 @@ __gnttab_unmap_common( PIN_FAIL(unmap_out, GNTST_general_error, "Bad frame number doesn't match gntref. (%lx != %lx)\n", op->frame, act->frame); - if ( op->flags & GNTMAP_device_map ) - { - ASSERT(act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask)); - op->map->flags &= ~GNTMAP_device_map; - if ( op->flags & GNTMAP_readonly ) - act->pin -= GNTPIN_devr_inc; - else - act->pin -= GNTPIN_devw_inc; - } + + op->map->flags &= ~GNTMAP_device_map; } if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) ) @@ -923,12 +916,7 @@ __gnttab_unmap_common( op->flags)) < 0 ) goto unmap_out; - ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)); op->map->flags &= ~GNTMAP_host_map; - if ( op->flags & GNTMAP_readonly ) - act->pin -= GNTPIN_hstr_inc; - else - act->pin -= GNTPIN_hstw_inc; } if ( is_pv_domain(ld) && need_iommu(ld) ) @@ -1016,6 +1004,12 @@ __gnttab_unmap_common_complete(struct gn else put_page_and_type(pg); } + + ASSERT(act->pin & (GNTPIN_devw_mask | GNTPIN_devr_mask)); + if ( op->flags & GNTMAP_readonly ) + act->pin -= GNTPIN_devr_inc; + else + act->pin -= GNTPIN_devw_inc; } if ( (op->host_addr != 0) && (op->flags & GNTMAP_host_map) ) @@ -1024,7 +1018,9 @@ __gnttab_unmap_common_complete(struct gn { /* * Suggests that __gntab_unmap_common failed in - * replace_grant_host_mapping() so nothing further to do + * replace_grant_host_mapping() or IOMMU handling, so nothing + * further to do (short of re-establishing the mapping in the + * latter case). */ goto unmap_out; } @@ -1035,6 +1031,12 @@ __gnttab_unmap_common_complete(struct gn put_page_type(pg); put_page(pg); } + + ASSERT(act->pin & (GNTPIN_hstw_mask | GNTPIN_hstr_mask)); + if ( op->flags & GNTMAP_readonly ) + act->pin -= GNTPIN_hstr_inc; + else + act->pin -= GNTPIN_hstw_inc; } if ( (op->map->flags & (GNTMAP_device_map|GNTMAP_host_map)) == 0 )
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