From: Paul Durrant <[email protected]>
At the moment pages are marked dirty by open-coded calls to
mark_page_dirty_in_slot(), directly deferefencing the gpa and memslot
from the cache. After a subsequent patch these may not always be set
so add a helper now so that caller will protected from the need to know
about this detail.
Signed-off-by: Paul Durrant <[email protected]>
Reviewed-by: David Woodhouse <[email protected]>
---
Cc: David Woodhouse <[email protected]>
Cc: Sean Christopherson <[email protected]>
Cc: Paolo Bonzini <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Dave Hansen <[email protected]>
Cc: "H. Peter Anvin" <[email protected]>
Cc: [email protected]
v13:
- s/kvm_gpc_mark_dirty/kvm_gpc_mark_dirty_in_slot
- Add a check for a NULL memslot pointer
v8:
- Make the helper a static inline.
---
arch/x86/kvm/x86.c | 2 +-
arch/x86/kvm/xen.c | 6 +++---
include/linux/kvm_host.h | 13 +++++++++++++
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b66c45e7f6f8..16269430006f 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3151,7 +3151,7 @@ static void kvm_setup_guest_pvclock(struct kvm_vcpu *v,
guest_hv_clock->version = ++vcpu->hv_clock.version;
- mark_page_dirty_in_slot(v->kvm, gpc->memslot, gpc->gpa >> PAGE_SHIFT);
+ kvm_gpc_mark_dirty_in_slot(gpc);
read_unlock_irqrestore(&gpc->lock, flags);
trace_kvm_pvclock_update(v->vcpu_id, &vcpu->hv_clock);
diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
index f3327508ae41..2d001a9c6378 100644
--- a/arch/x86/kvm/xen.c
+++ b/arch/x86/kvm/xen.c
@@ -453,11 +453,11 @@ static void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, bool atomic)
}
if (user_len2) {
- mark_page_dirty_in_slot(v->kvm, gpc2->memslot, gpc2->gpa >> PAGE_SHIFT);
+ kvm_gpc_mark_dirty_in_slot(gpc2);
read_unlock(&gpc2->lock);
}
- mark_page_dirty_in_slot(v->kvm, gpc1->memslot, gpc1->gpa >> PAGE_SHIFT);
+ kvm_gpc_mark_dirty_in_slot(gpc1);
read_unlock_irqrestore(&gpc1->lock, flags);
}
@@ -565,7 +565,7 @@ void kvm_xen_inject_pending_events(struct kvm_vcpu *v)
WRITE_ONCE(vi->evtchn_upcall_pending, 1);
}
- mark_page_dirty_in_slot(v->kvm, gpc->memslot, gpc->gpa >> PAGE_SHIFT);
+ kvm_gpc_mark_dirty_in_slot(gpc);
read_unlock_irqrestore(&gpc->lock, flags);
/* For the per-vCPU lapic vector, deliver it as MSI. */
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index bbfefd7e612f..5a27b4389d32 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -1398,6 +1398,19 @@ int kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, unsigned long len);
*/
void kvm_gpc_deactivate(struct gfn_to_pfn_cache *gpc);
+/**
+ * kvm_gpc_mark_dirty_in_slot - mark a cached guest page as dirty.
+ *
+ * @gpc: struct gfn_to_pfn_cache object.
+ */
+static inline void kvm_gpc_mark_dirty_in_slot(struct gfn_to_pfn_cache *gpc)
+{
+ lockdep_assert_held(&gpc->lock);
+ if (gpc->memslot)
+ mark_page_dirty_in_slot(gpc->kvm, gpc->memslot,
+ gpc->gpa >> PAGE_SHIFT);
+}
+
void kvm_sigset_activate(struct kvm_vcpu *vcpu);
void kvm_sigset_deactivate(struct kvm_vcpu *vcpu);
--
2.39.2
On Thu, Feb 15, 2024, Paul Durrant wrote:
> +/**
> + * kvm_gpc_mark_dirty_in_slot - mark a cached guest page as dirty.
> + *
> + * @gpc: struct gfn_to_pfn_cache object.
Meh, just omit the kerneldoc comment.
> + */
> +static inline void kvm_gpc_mark_dirty_in_slot(struct gfn_to_pfn_cache *gpc)
> +{
> + lockdep_assert_held(&gpc->lock);
> + if (gpc->memslot)
> + mark_page_dirty_in_slot(gpc->kvm, gpc->memslot,
> + gpc->gpa >> PAGE_SHIFT);
It's kinda silly, but I think it's worth landing this below gpa_to_gfn() so that
there's no need to open code the shift.
And I have a (very) slight preference for an early return.
static inline void kvm_gpc_mark_dirty_in_slot(struct gfn_to_pfn_cache *gpc)
{
lockdep_assert_held(&gpc->lock);
if (!gpc->memslot)
return;
mark_page_dirty_in_slot(gpc->kvm, gpc->memslot, gpa_to_gfn(gpc->gpa));
}
> +}
> +
> void kvm_sigset_activate(struct kvm_vcpu *vcpu);
> void kvm_sigset_deactivate(struct kvm_vcpu *vcpu);
>
> --
> 2.39.2
>
On 19/02/2024 21:42, Sean Christopherson wrote:
> On Thu, Feb 15, 2024, Paul Durrant wrote:
>> +/**
>> + * kvm_gpc_mark_dirty_in_slot - mark a cached guest page as dirty.
>> + *
>> + * @gpc: struct gfn_to_pfn_cache object.
>
> Meh, just omit the kerneldoc comment.
>
>> + */
>> +static inline void kvm_gpc_mark_dirty_in_slot(struct gfn_to_pfn_cache *gpc)
>> +{
>> + lockdep_assert_held(&gpc->lock);
>> + if (gpc->memslot)
>> + mark_page_dirty_in_slot(gpc->kvm, gpc->memslot,
>> + gpc->gpa >> PAGE_SHIFT);
>
> It's kinda silly, but I think it's worth landing this below gpa_to_gfn() so that
> there's no need to open code the shift.
>
> And I have a (very) slight preference for an early return.
>
> static inline void kvm_gpc_mark_dirty_in_slot(struct gfn_to_pfn_cache *gpc)
> {
> lockdep_assert_held(&gpc->lock);
>
> if (!gpc->memslot)
> return;
>
> mark_page_dirty_in_slot(gpc->kvm, gpc->memslot, gpa_to_gfn(gpc->gpa));
> }
>
Ok. Will change.
>> +}
>> +
>> void kvm_sigset_activate(struct kvm_vcpu *vcpu);
>> void kvm_sigset_deactivate(struct kvm_vcpu *vcpu);
>>
>> --
>> 2.39.2
>>