From: Sean Christopherson <seanjc@google.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, mhal@rbox.co
Subject: Re: [PATCH 03/16] KVM: x86: set gfn-to-pfn cache length consistently with VM word size
Date: Thu, 27 Oct 2022 17:22:51 +0000 [thread overview]
Message-ID: <Y1q+a3gtABqJPmmr@google.com> (raw)
In-Reply-To: <20221027161849.2989332-4-pbonzini@redhat.com>
On Thu, Oct 27, 2022, Paolo Bonzini wrote:
> So, use the short size at activation time as well. This means
> re-activating the cache if the guest requests the hypercall page
> multiple times with different word sizes (this can happen when
> kexec-ing, for example).
I don't understand the motivation for allowing a conditionally valid GPA. I see
a lot of complexity and sub-optimal error handling for a use case that no one
cares about. Realistically, userspace is never going to provide a GPA that only
works some of the time, because doing otherwise is just asking for a dead guest.
> +static int kvm_xen_reactivate_runstate_gpcs(struct kvm *kvm)
> +{
> + struct kvm_vcpu *vcpu;
> + unsigned long i;
> +
> + kvm_for_each_vcpu(i, vcpu, kvm) {
> + if (vcpu->arch.xen.runstate_cache.active) {
This is not safe when called from kvm_xen_write_hypercall_page(), which doesn't
acquire kvm->lock and thus doesn't guard against a concurrent call via
kvm_xen_vcpu_set_attr(). That's likely a bug in itself, but even if that issue
is fixed, I don't see how this is yields a better uAPI than forcing userspace to
provide an address that is valid for all modes.
If the address becomes bad when the guest changes the hypercall page, the guest
is completely hosed through no fault of its own, whereas limiting the misaligned
detection to KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_ADDR means that any "bad" address
will result in immediate failure, i.e. makes it so that errors are 100% userspace
misconfiguration bugs.
> + int r = kvm_xen_activate_runstate_gpc(vcpu,
> + vcpu->arch.xen.runstate_cache.gpa);
> + if (r < 0)
Returning immediately is wrong, as later vCPUs will have a valid, active cache
that hasn't been verified for 64-bit mode.
> + return r;
> + }
> + }
> + return 0;
> +}
> +
> void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state)
> {
> struct kvm_vcpu_xen *vx = &v->arch.xen;
> @@ -212,11 +243,7 @@ void kvm_xen_update_runstate_guest(struct kvm_vcpu *v, int state)
> if (!vx->runstate_cache.active)
> return;
>
> - if (IS_ENABLED(CONFIG_64BIT) && v->kvm->arch.xen.long_mode)
> - user_len = sizeof(struct vcpu_runstate_info);
> - else
> - user_len = sizeof(struct compat_vcpu_runstate_info);
> -
> + user_len = kvm_xen_runstate_info_size(v->kvm);
> read_lock_irqsave(&gpc->lock, flags);
> while (!kvm_gfn_to_pfn_cache_check(v->kvm, gpc, gpc->gpa,
> user_len)) {
> @@ -461,7 +488,7 @@ int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data)
> mutex_lock(&kvm->lock);
> kvm->arch.xen.long_mode = !!data->u.long_mode;
> mutex_unlock(&kvm->lock);
> - r = 0;
> + r = kvm_xen_reactivate_runstate_gpcs(kvm);
Needs to be called under kvm->lock. This path also needs to acquire kvm->srcu.
> }
> break;
>
> @@ -596,9 +623,7 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
> break;
> }
>
> - r = kvm_gpc_activate(vcpu->kvm, &vcpu->arch.xen.runstate_cache,
> - NULL, KVM_HOST_USES_PFN, data->u.gpa,
> - sizeof(struct vcpu_runstate_info));
> + r = kvm_xen_activate_runstate_gpc(vcpu, data->u.gpa);
> break;
>
> case KVM_XEN_VCPU_ATTR_TYPE_RUNSTATE_CURRENT:
> @@ -843,9 +868,13 @@ int kvm_xen_write_hypercall_page(struct kvm_vcpu *vcpu, u64 data)
> u32 page_num = data & ~PAGE_MASK;
> u64 page_addr = data & PAGE_MASK;
> bool lm = is_long_mode(vcpu);
> + int r;
>
> /* Latch long_mode for shared_info pages etc. */
> vcpu->kvm->arch.xen.long_mode = lm;
> + r = kvm_xen_reactivate_runstate_gpcs(kvm);
> + if (r < 0)
> + return 1;
Aren't we just making up behavior at this point? Injecting a #GP into the guest
for what is a completely legal operation from the guest's perspective seems all
kinds of wrong.
next prev parent reply other threads:[~2022-10-27 17:22 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-10-27 16:18 [PATCH v3 00/16] KVM: x86: Always use non-compat vcpu_runstate_info size for gfn=>pfn cache Paolo Bonzini
2022-10-27 16:18 ` [PATCH 01/16] KVM: Initialize gfn_to_pfn_cache locks in dedicated helper Paolo Bonzini
2022-10-27 16:18 ` [PATCH 02/16] KVM: Reject attempts to consume or refresh inactive gfn_to_pfn_cache Paolo Bonzini
2022-10-27 16:18 ` [PATCH 03/16] KVM: x86: set gfn-to-pfn cache length consistently with VM word size Paolo Bonzini
2022-10-27 17:22 ` Sean Christopherson [this message]
2022-10-28 11:36 ` Paolo Bonzini
2022-10-28 16:31 ` Sean Christopherson
2022-11-13 13:32 ` David Woodhouse
2022-11-13 13:36 ` David Woodhouse
2022-11-14 11:27 ` Durrant, Paul
2022-11-15 0:16 ` David Woodhouse
2022-11-16 22:49 ` David Woodhouse
[not found] ` <994314051112513787cc4bd0c7d2694e15190d0f.camel@amazon.co.uk>
2022-11-14 16:33 ` Sean Christopherson
2022-11-14 17:36 ` [EXTERNAL][PATCH " David Woodhouse
2022-11-14 16:58 ` [PATCH " Paolo Bonzini
2022-10-27 16:18 ` [PATCH 04/16] KVM: Shorten gfn_to_pfn_cache function names Paolo Bonzini
2022-10-27 16:18 ` [PATCH 05/16] KVM: x86: Remove unused argument in gpc_unmap_khva() Paolo Bonzini
2022-10-27 16:18 ` [PATCH 06/16] KVM: Store immutable gfn_to_pfn_cache properties Paolo Bonzini
2022-10-27 16:18 ` [PATCH 07/16] KVM: Store gfn_to_pfn_cache length at activation time Paolo Bonzini
2022-10-27 16:18 ` [PATCH 08/16] KVM: Use gfn_to_pfn_cache's immutable "kvm" in kvm_gpc_check() Paolo Bonzini
2022-10-27 16:18 ` [PATCH 09/16] KVM: Clean up hva_to_pfn_retry() Paolo Bonzini
2022-10-27 16:18 ` [PATCH 10/16] KVM: Use gfn_to_pfn_cache's immutable "kvm" in kvm_gpc_refresh() Paolo Bonzini
2022-10-27 16:18 ` [PATCH 11/16] KVM: Drop KVM's API to allow temprorarily unmapping gfn=>pfn cache Paolo Bonzini
2022-10-27 16:18 ` [PATCH 12/16] KVM: Do not partially reinitialize gfn=>pfn cache during activation Paolo Bonzini
2022-10-27 16:18 ` [PATCH 13/16] KVM: Drop @gpa from exported gfn=>pfn cache check() and refresh() helpers Paolo Bonzini
2022-10-27 16:18 ` [PATCH 14/16] KVM: Skip unnecessary "unmap" if gpc is already valid during refresh Paolo Bonzini
2022-10-27 16:18 ` [PATCH 15/16] KVM: selftests: Add tests in xen_shinfo_test to detect lock races Paolo Bonzini
2022-10-27 16:18 ` [PATCH 16/16] KVM: selftests: Mark "guest_saw_irq" as volatile in xen_shinfo_test Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Y1q+a3gtABqJPmmr@google.com \
--to=seanjc@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mhal@rbox.co \
--cc=pbonzini@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox