From: Sean Christopherson <seanjc@google.com>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Subject: Re: [PATCH 1/6] KVM: x86: inline kernel_pio into its sole caller
Date: Thu, 9 Jun 2022 21:33:29 +0000 [thread overview]
Message-ID: <YqJnKSpnPFZ5VsnL@google.com> (raw)
In-Reply-To: <20220608121253.867333-2-pbonzini@redhat.com>
On Wed, Jun 08, 2022, Paolo Bonzini wrote:
> The caller of kernel_pio already has arguments for most of what kernel_pio
> fishes out of vcpu->arch.pio. This is the first step towards ensuring that
> vcpu->arch.pio.* is only used when exiting to userspace.
>
> We can now also WARN if emulated PIO performs successful in-kernel iterations
> before having to fall back to userspace. The code is not ready for that, and
> it should never happen.
Please avoid pronouns and state what patch does, not what "can" be done. It's not
clear without reading the actual code whether "The code is not ready for that" means
"KVM is not ready to WARN" or "KVM is not ready to fall back to exiting userspace
if a
E.g.
WARN if emulated PIO falls back to userspace after successfully handling
one or more in-kernel iterations. The port, size, and access type do not
change, and KVM so it should be impossible for in-kernel PIO to fail on
subsequent iterations.
That said, I don't think the above statement is true. KVM is running with SRCU
protection, but the synchronize_srcu_expedited() in kvm_io_bus_unregister_dev()
only protects against use-after-free, it does not prevent two calls to
kvm_io_bus_read() from seeing different incarnations of kvm->buses.
And if I'm right, that could be exploited to create a buffer overrun due to doing
this memcpy with "data = <original data> + i * size".
else
memcpy(vcpu->arch.pio_data, data, size * count);
The existing code is arguably wrong too in that it will result in replaying PIO
accesses, but IMO userspace gets to keep the pieces if it unregisters a device
while vCPUs are running.
> No functional change intended.
>
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
> arch/x86/kvm/x86.c | 39 +++++++++++++++++----------------------
> 1 file changed, 17 insertions(+), 22 deletions(-)
>
> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> index 79efdc19b4c8..2f9100f2564e 100644
> --- a/arch/x86/kvm/x86.c
> +++ b/arch/x86/kvm/x86.c
> @@ -7415,37 +7415,32 @@ static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
> return emulator_write_emulated(ctxt, addr, new, bytes, exception);
> }
>
> -static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
> -{
> - int r = 0, i;
> -
> - for (i = 0; i < vcpu->arch.pio.count; i++) {
> - if (vcpu->arch.pio.in)
> - r = kvm_io_bus_read(vcpu, KVM_PIO_BUS, vcpu->arch.pio.port,
> - vcpu->arch.pio.size, pd);
> - else
> - r = kvm_io_bus_write(vcpu, KVM_PIO_BUS,
> - vcpu->arch.pio.port, vcpu->arch.pio.size,
> - pd);
> - if (r)
> - break;
> - pd += vcpu->arch.pio.size;
> - }
> - return r;
> -}
> -
> static int emulator_pio_in_out(struct kvm_vcpu *vcpu, int size,
> unsigned short port,
> unsigned int count, bool in)
> {
> + void *data = vcpu->arch.pio_data;
> + unsigned i;
> + int r;
> +
> vcpu->arch.pio.port = port;
> vcpu->arch.pio.in = in;
> - vcpu->arch.pio.count = count;
> + vcpu->arch.pio.count = count;
> vcpu->arch.pio.size = size;
>
> - if (!kernel_pio(vcpu, vcpu->arch.pio_data))
> - return 1;
> + for (i = 0; i < count; i++) {
> + if (in)
> + r = kvm_io_bus_read(vcpu, KVM_PIO_BUS, port, size, data);
> + else
> + r = kvm_io_bus_write(vcpu, KVM_PIO_BUS, port, size, data);
> + if (r)
> + goto userspace_io;
> + data += size;
> + }
> + return 1;
>
> +userspace_io:
> + WARN_ON(i != 0);
> vcpu->run->exit_reason = KVM_EXIT_IO;
> vcpu->run->io.direction = in ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT;
> vcpu->run->io.size = size;
> --
> 2.31.1
>
>
next prev parent reply other threads:[~2022-06-09 21:33 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-06-08 12:12 [PATCH 0/6] KVM: x86: vcpu->arch.pio* cleanups Paolo Bonzini
2022-06-08 12:12 ` [PATCH 1/6] KVM: x86: inline kernel_pio into its sole caller Paolo Bonzini
2022-06-09 21:33 ` Sean Christopherson [this message]
2022-06-08 12:12 ` [PATCH 2/6] KVM: x86: move all vcpu->arch.pio* setup in emulator_pio_in_out Paolo Bonzini
2022-06-09 22:03 ` Sean Christopherson
2022-06-08 12:12 ` [PATCH 3/6] KVM: x86: wean in-kernel PIO from vcpu->arch.pio* Paolo Bonzini
2022-06-09 22:19 ` Sean Christopherson
2022-06-08 12:12 ` [PATCH 4/6] KVM: x86: wean fast IN from emulator_pio_in Paolo Bonzini
2022-06-09 22:37 ` Sean Christopherson
2022-06-08 12:12 ` [PATCH 5/6] KVM: x86: de-underscorify __emulator_pio_in Paolo Bonzini
2022-06-09 22:42 ` Sean Christopherson
2022-06-08 12:12 ` [PATCH 6/6] KVM: SEV-ES: reuse advance_sev_es_emulated_ins for OUT too Paolo Bonzini
2022-06-09 22:50 ` Sean Christopherson
2022-06-15 14:41 ` 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=YqJnKSpnPFZ5VsnL@google.com \
--to=seanjc@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.