Message ID | 7ae3d49bf9ce153a5460a393bfa513a585930487.1486377433.git-series.james.hogan@imgtec.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 06/02/2017 11:46, James Hogan wrote: > Documentation/virtual/kvm/api.txt seems to suggest that > KVM_EXIT_HYPERCALL is obsolete. When it suggests using KVM_EXIT_MMIO, > does it simply mean the guest should use MMIO to some virtio device of > some sort rather than using hypercalls, or that the hypercall should > somehow be munged into the mmio exit information? The former. But there are cases when using hypercalls is unavoidable. In that case the trend is to use other exit reasons than KVM_EXIT_HYPERCALL, such as KVM_EXIT_PAPR_HCALL in PowerPC. Feel free to add KVM_EXIT_MIPS_CONOUT or something like that. How would you find the character device to write to in QEMU? Paolo
On Mon, Feb 06, 2017 at 02:25:59PM +0100, Paolo Bonzini wrote: > > > On 06/02/2017 11:46, James Hogan wrote: > > Documentation/virtual/kvm/api.txt seems to suggest that > > KVM_EXIT_HYPERCALL is obsolete. When it suggests using KVM_EXIT_MMIO, > > does it simply mean the guest should use MMIO to some virtio device of > > some sort rather than using hypercalls, or that the hypercall should > > somehow be munged into the mmio exit information? > > The former. Okay, thanks. > > But there are cases when using hypercalls is unavoidable. In that case > the trend is to use other exit reasons than KVM_EXIT_HYPERCALL, such as > KVM_EXIT_PAPR_HCALL in PowerPC. Feel free to add KVM_EXIT_MIPS_CONOUT > or something like that. Okay, that sounds sensible. The existing mips_paravirt_defconfig does contain CONFIG_VIRTIO_CONSOLE=y though, so I'm thinking we may be able to get away without this hypercall and without old paravirt guest kernels becoming unusable. David/Andreas: would you agree, or do you feel strongly that this hypercall API should be kept? (with a different KVM exit reason) > > How would you find the character device to write to in QEMU? I imagine it'd need a custom character device driver in QEMU so it could be wired up to stdio/pty or whatever using QEMU arguments. I've only tested it with a test case in my own MIPS KVM test suite so far though. Cheers James
diff --git a/Documentation/virtual/kvm/hypercalls.txt b/Documentation/virtual/kvm/hypercalls.txt index f8108c84c46b..4e6e57026bfe 100644 --- a/Documentation/virtual/kvm/hypercalls.txt +++ b/Documentation/virtual/kvm/hypercalls.txt @@ -98,3 +98,13 @@ Purpose: Return the frequency of CP0_Count in HZ. Architecture: mips Status: active Purpose: Shut down the virtual machine. + +8. KVM_HC_MIPS_CONSOLE_OUTPUT +------------------------ +Architecture: mips +Status: active +Purpose: Output a string to a console. +Argument 1 contains the virtual terminal number to write to. +Argument 2 contains a guest virtual address pointer to the string, which must +be in an unmapped virtual memory segment (e.g. KSeg0, KSeg1 or XKPhys). +Argument 3 contains the number of bytes to write. diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h index 0d308d4f2429..e0f1da0c35e9 100644 --- a/arch/mips/include/asm/kvm_host.h +++ b/arch/mips/include/asm/kvm_host.h @@ -309,6 +309,9 @@ struct kvm_vcpu_arch { /* GPR used as IO source/target */ u32 io_gpr; + /* Whether a hypercall needs completing */ + int hypercall_needed; + struct hrtimer comparecount_timer; /* Count timer control KVM register */ u32 count_ctl; @@ -838,6 +841,7 @@ unsigned int kvm_mips_config5_wrmask(struct kvm_vcpu *vcpu); enum emulation_result kvm_mips_emul_hypcall(struct kvm_vcpu *vcpu, union mips_instruction inst); int kvm_mips_handle_hypcall(struct kvm_vcpu *vcpu); +void kvm_mips_complete_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run); /* Dynamic binary translation */ extern int kvm_mips_trans_cache_index(union mips_instruction inst, diff --git a/arch/mips/kvm/hypcall.c b/arch/mips/kvm/hypcall.c index c3345e5eec02..9cb8f37ca43a 100644 --- a/arch/mips/kvm/hypcall.c +++ b/arch/mips/kvm/hypcall.c @@ -33,6 +33,7 @@ static int kvm_mips_hypercall(struct kvm_vcpu *vcpu, unsigned long num, const unsigned long *args, unsigned long *hret) { int ret = RESUME_GUEST; + int i; switch (num) { case KVM_HC_MIPS_GET_CLOCK_FREQ: @@ -49,6 +50,19 @@ static int kvm_mips_hypercall(struct kvm_vcpu *vcpu, unsigned long num, ret = RESUME_HOST; break; + /* Hypercalls passed to userland to handle */ + case KVM_HC_MIPS_CONSOLE_OUTPUT: + /* Pass to userland via KVM_EXIT_HYPERCALL */ + memset(&vcpu->run->hypercall, 0, sizeof(vcpu->run->hypercall)); + vcpu->run->hypercall.nr = num; + for (i = 0; i < MAX_HYPCALL_ARGS; ++i) + vcpu->run->hypercall.args[i] = args[i]; + vcpu->run->hypercall.ret = -KVM_ENOSYS; /* default */ + vcpu->run->exit_reason = KVM_EXIT_HYPERCALL; + vcpu->arch.hypercall_needed = 1; + ret = RESUME_HOST; + break; + default: /* Report unimplemented hypercall to guest */ *hret = -KVM_ENOSYS; @@ -72,3 +86,9 @@ int kvm_mips_handle_hypcall(struct kvm_vcpu *vcpu) return kvm_mips_hypercall(vcpu, num, args, &vcpu->arch.gprs[2] /* v0 */); } + +void kvm_mips_complete_hypercall(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + vcpu->arch.gprs[2] = run->hypercall.ret; /* v0 */ + vcpu->arch.hypercall_needed = 0; +} diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c index 31ee5ee0010b..1c23dc29db5d 100644 --- a/arch/mips/kvm/mips.c +++ b/arch/mips/kvm/mips.c @@ -409,6 +409,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) vcpu->mmio_needed = 0; } + if (vcpu->arch.hypercall_needed) + kvm_mips_complete_hypercall(vcpu, run); + lose_fpu(1); local_irq_disable();
Implement console output hypercall by exiting back to userland with KVM_EXIT_HYPERCALL, and setting the return value on next KVM_RUN. We also document the hypercall along with the others as the documentation was never added Signed-off-by: James Hogan <james.hogan@imgtec.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: "Radim Krčmář" <rkrcmar@redhat.com> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Andreas Herrmann <andreas.herrmann@caviumnetworks.com> Cc: David Daney <david.daney@cavium.com> Cc: Jonathan Corbet <corbet@lwn.net> Cc: linux-mips@linux-mips.org Cc: kvm@vger.kernel.org Cc: linux-doc@vger.kernel.org --- Documentation/virtual/kvm/api.txt seems to suggest that KVM_EXIT_HYPERCALL is obsolete. When it suggests using KVM_EXIT_MMIO, does it simply mean the guest should use MMIO to some virtio device of some sort rather than using hypercalls, or that the hypercall should somehow be munged into the mmio exit information? --- Documentation/virtual/kvm/hypercalls.txt | 10 ++++++++++ arch/mips/include/asm/kvm_host.h | 4 ++++ arch/mips/kvm/hypcall.c | 20 ++++++++++++++++++++ arch/mips/kvm/mips.c | 3 +++ 4 files changed, 37 insertions(+), 0 deletions(-)