@@ -10379,6 +10379,15 @@ static int vcpu_enter_guest(struct kvm_vcpu
*vcpu)
r = 0;
goto out;
}
+ if (kvm_check_request(KVM_REQ_DIRTY_QUOTA_EXIT, vcpu)) {
+ struct kvm_run *run = vcpu->run;
+
+ run->exit_reason = KVM_EXIT_DIRTY_QUOTA_EXHAUSTED;
+ run->dirty_quota_exit.count =
vcpu->stat.generic.pages_dirtied;
+ run->dirty_quota_exit.quota = vcpu->dirty_quota;
As mentioned in patch 1, the code code snippet I suggested is bad.
With a request,
there's no need to snapshot the quota prior to making the request. If
userspace
changes the quota, then using the new quota is perfectly ok since KVM
is still
providing sane data. If userspace lowers the quota, an exit will
still ocurr as
expected. If userspace disables or increases the quota to the point
where no exit
is necessary, then userspace can't expect and exit and won't even be
aware that KVM
temporarily detected an exhausted quota.
And all of this belongs in a common KVM helper. Name isn't pefect,
but it aligns
with kvm_check_request().
#ifdef CONFIG_HAVE_KVM_DIRTY_QUOTA
static inline bool kvm_check_dirty_quota_request(struct kvm_vcpu *vcpu)
{
struct kvm_run *run = vcpu->run;
run->exit_reason = KVM_EXIT_DIRTY_QUOTA_EXHAUSTED;
run->dirty_quota_exit.count = vcpu->stat.generic.pages_dirtied;
run->dirty_quota_exit.quota = READ_ONCE(run->dirty_quota);
/*
* Re-check the quota and exit if and only if the vCPU still
exceeds its
* quota. If userspace increases (or disables entirely) the
quota, then
* no exit is required as KVM is still honoring its ABI, e.g.
userspace
* won't even be aware that KVM temporarily detected an exhausted
quota.
*/
return run->dirty_quota_exit.count >= run->dirty_quota_exit.quota;
}
#endif
And then arch usage is simply something like:
if (kvm_check_dirty_quota_request(vcpu)) {
r = 0;
goto out;
}
If we are not even checking for request KVM_REQ_DIRTY_QUOTA_EXIT, what's
the use of kvm_make_request in patch 1?
Ok, so we don't need to explicitely check for request here because we
are checking the quota directly but we do need to make the request when
the quota is exhausted so as to guarantee that we enter the if block "if
(kvm_request_pending(vcpu))".
Please let me know if my understanding is correct or if I am missing
something.
Also, should I add ifdef here:
#ifdef CONFIG_HAVE_KVM_DIRTY_QUOTA
if (kvm_check_dirty_quota_request(vcpu)) {
r = 0;
goto out;
}
#endif
Or should I bring the ifdef inside kvm_check_dirty_quota_request and
return false if not defined.
static inline bool kvm_check_dirty_quota_request(struct kvm_vcpu *vcpu)
{
#ifdef CONFIG_HAVE_KVM_DIRTY_QUOTA
struct kvm_run *run = vcpu->run;
run->exit_reason = KVM_EXIT_DIRTY_QUOTA_EXHAUSTED;
run->dirty_quota_exit.count = vcpu->stat.generic.pages_dirtied;
run->dirty_quota_exit.quota = READ_ONCE(run->dirty_quota);
/*
* Re-check the quota and exit if and only if the vCPU still exceeds its
* quota. If userspace increases (or disables entirely) the quota, then
* no exit is required as KVM is still honoring its ABI, e.g. userspace
* won't even be aware that KVM temporarily detected an exhausted quota.
*/
return run->dirty_quota_exit.count >= run->dirty_quota_exit.quota;
#else
return false;
#endif
}
Thanks a lot for the reviews so far. Looking forward to your reply.