On 01/02/2023 14:31, David Woodhouse wrote:
> From: David Woodhouse <dwmw@amazon.co.uk>
>
> Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
> ---
> hw/i386/kvm/xen_evtchn.c | 32 ++++++++++++++++++++++++++++++++
> hw/i386/kvm/xen_evtchn.h | 2 ++
> target/i386/kvm/xen-emu.c | 15 +++++++++++++++
> 3 files changed, 49 insertions(+)
>
> diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c
> index a97d6ba61d..9dc5a98d94 100644
> --- a/hw/i386/kvm/xen_evtchn.c
> +++ b/hw/i386/kvm/xen_evtchn.c
> @@ -835,6 +835,38 @@ int xen_evtchn_bind_ipi_op(struct evtchn_bind_ipi *ipi)
> return ret;
> }
>
> +int xen_evtchn_alloc_unbound_op(struct evtchn_alloc_unbound *alloc)
> +{
> + XenEvtchnState *s = xen_evtchn_singleton;
> + uint16_t type_val;
> + int ret;
> +
> + if (!s) {
> + return -ENOTSUP;
> + }
> +
> + if (alloc->dom != DOMID_SELF && alloc->dom != xen_domid) {
> + return -ESRCH;
> + }
> +
> + if (alloc->remote_dom == DOMID_QEMU) {
> + type_val = PORT_INFO_TYPEVAL_REMOTE_QEMU;
> + } else if (alloc->remote_dom == DOMID_SELF ||
> + alloc->remote_dom == xen_domid) {
> + type_val = 0;
> + } else {
> + return -EPERM;
> + }
> +
> + qemu_mutex_lock(&s->port_lock);
> +
> + ret = allocate_port(s, 0, EVTCHNSTAT_unbound, type_val, &alloc->port);
> +
> + qemu_mutex_unlock(&s->port_lock);
> +
> + return ret;
> +}
> +
> int xen_evtchn_send_op(struct evtchn_send *send)
> {
> XenEvtchnState *s = xen_evtchn_singleton;
> diff --git a/hw/i386/kvm/xen_evtchn.h b/hw/i386/kvm/xen_evtchn.h
> index 500fdbe8b8..fc080138e3 100644
> --- a/hw/i386/kvm/xen_evtchn.h
> +++ b/hw/i386/kvm/xen_evtchn.h
> @@ -21,11 +21,13 @@ struct evtchn_unmask;
> struct evtchn_bind_virq;
> struct evtchn_bind_ipi;
> struct evtchn_send;
> +struct evtchn_alloc_unbound;
> int xen_evtchn_status_op(struct evtchn_status *status);
> int xen_evtchn_close_op(struct evtchn_close *close);
> int xen_evtchn_unmask_op(struct evtchn_unmask *unmask);
> int xen_evtchn_bind_virq_op(struct evtchn_bind_virq *virq);
> int xen_evtchn_bind_ipi_op(struct evtchn_bind_ipi *ipi);
> int xen_evtchn_send_op(struct evtchn_send *send);
> +int xen_evtchn_alloc_unbound_op(struct evtchn_alloc_unbound *alloc);
>
> #endif /* QEMU_XEN_EVTCHN_H */
> diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c
> index 5299614d3c..e186dec9a9 100644
> --- a/target/i386/kvm/xen-emu.c
> +++ b/target/i386/kvm/xen-emu.c
> @@ -918,6 +918,21 @@ static bool kvm_xen_hcall_evtchn_op(struct kvm_xen_exit *exit, X86CPU *cpu,
> err = xen_evtchn_send_op(&send);
> break;
> }
> + case EVTCHNOP_alloc_unbound: {
> + struct evtchn_alloc_unbound alloc;
> +
> + qemu_build_assert(sizeof(alloc) == 8);
Why?
Paul
> + if (kvm_copy_from_gva(cs, arg, &alloc, sizeof(alloc))) {
> + err = -EFAULT;
> + break;
> + }
> +
> + err = xen_evtchn_alloc_unbound_op(&alloc);
> + if (!err && kvm_copy_to_gva(cs, arg, &alloc, sizeof(alloc))) {
> + err = -EFAULT;
> + }
> + break;
> + }
> default:
> return false;
> }