x86/mm: Don't re-set PGT_pinned on a partially de-validated page
authorGeorge Dunlap <george.dunlap@citrix.com>
Thu, 31 Oct 2019 16:08:08 +0000 (17:08 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 31 Oct 2019 16:08:08 +0000 (17:08 +0100)
commit535051419eab5629ceb725ec0636eed20f592262
treec45961af75d4fcc1b74cd16646af19638ffa5b67
parent19bb4f51f950beb5cae86371f4b5d42020c5f49f
x86/mm: Don't re-set PGT_pinned on a partially de-validated page

When unpinning pagetables, if an operation is interrupted,
relinquish_memory() re-sets PGT_pinned so that the un-pin will
pickedup again when the hypercall restarts.

This is appropriate when put_page_and_type_preemptible() returns
-EINTR, which indicates that the page is back in its initial state
(i.e., completely validated).  However, for -ERESTART, this leads to a
state where a page has both PGT_pinned and PGT_partial set.

This happens to work at the moment, although it's not really a
"canonical" state; but in subsequent patches, where we need to make a
distinction in handling between PGT_validated and PGT_partial pages,
this causes issues.

Move to a "canonical" state by:
- Only re-setting PGT_pinned on -EINTR
- Re-dropping the refcount held by PGT_pinned on -ERESTART

In the latter case, the PGT_partial bit will be cleared further down
with the rest of the other PGT_partial pages.

While here, clean up some trainling whitespace.

This is part of XSA-299.

Reported-by: George Dunlap <george.dunlap@citrix.com>
Signed-off-by: George Dunlap <george.dunlap@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
master commit: bf656e02d8e7f49b484e2587aef4f18deda6e2ab
master date: 2019-10-31 16:11:46 +0100
xen/arch/x86/domain.c