From b4411416fee92cea6cd7a04bfda95bdf377f631e Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 6 Dec 2021 14:10:42 +0100 Subject: [PATCH] x86/shadow: defer/avoid paging_mfn_is_dirty() invocation paging_mfn_is_dirty() is moderately expensive, so avoid its use unless its result might actually change anything. This means moving the surrounding if() down below all other checks that can result in clearing _PAGE_RW from sflags, in order to then check whether _PAGE_RW is actually still set there before calling the function. While moving the block of code, fold two if()s and make a few style adjustments. Signed-off-by: Jan Beulich Reviewed-by: Tim Deegan --- xen/arch/x86/mm/shadow/multi.c | 36 ++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index 7b8f4dd13b..be617281fc 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -604,23 +604,6 @@ _sh_propagate(struct vcpu *v, && !(gflags & _PAGE_DIRTY)) ) sflags &= ~_PAGE_RW; - // shadow_mode_log_dirty support - // - // Only allow the guest write access to a page a) on a demand fault, - // or b) if the page is already marked as dirty. - // - // (We handle log-dirty entirely inside the shadow code, without using the - // p2m_ram_logdirty p2m type: only HAP uses that.) - if ( unlikely((level == 1) && shadow_mode_log_dirty(d)) ) - { - if ( mfn_valid(target_mfn) ) { - if ( ft & FETCH_TYPE_WRITE ) - paging_mark_dirty(d, target_mfn); - else if ( !paging_mfn_is_dirty(d, target_mfn) ) - sflags &= ~_PAGE_RW; - } - } - #ifdef CONFIG_HVM if ( unlikely(level == 1) && is_hvm_domain(d) ) { @@ -661,6 +644,25 @@ _sh_propagate(struct vcpu *v, ) ) sflags &= ~_PAGE_RW; + /* + * shadow_mode_log_dirty support + * + * Only allow the guest write access to a page a) on a demand fault, + * or b) if the page is already marked as dirty. + * + * (We handle log-dirty entirely inside the shadow code, without using the + * p2m_ram_logdirty p2m type: only HAP uses that.) + */ + if ( level == 1 && unlikely(shadow_mode_log_dirty(d)) && + mfn_valid(target_mfn) ) + { + if ( ft & FETCH_TYPE_WRITE ) + paging_mark_dirty(d, target_mfn); + else if ( (sflags & _PAGE_RW) && + !paging_mfn_is_dirty(d, target_mfn) ) + sflags &= ~_PAGE_RW; + } + // PV guests in 64-bit mode use two different page tables for user vs // supervisor permissions, making the guest's _PAGE_USER bit irrelevant. // It is always shadowed as present... -- 2.30.2