From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= Subject: [PATCH 5/9] KVM: support x2APIC ID in userspace routes Date: Fri, 6 May 2016 22:54:01 +0200 Message-ID: <1462568045-31085-6-git-send-email-rkrcmar@redhat.com> References: <1462568045-31085-1-git-send-email-rkrcmar@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: QUOTED-PRINTABLE Cc: Paolo Bonzini , "Lan, Tianyu" , Igor Mammedov , Jan Kiszka , Peter Xu To: kvm@vger.kernel.org Return-path: Received: from mx1.redhat.com ([209.132.183.28]:51885 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758275AbcEFUyf (ORCPT ); Fri, 6 May 2016 16:54:35 -0400 In-Reply-To: <1462568045-31085-1-git-send-email-rkrcmar@redhat.com> Sender: kvm-owner@vger.kernel.org List-ID: We need a way to pass 32 bit APIC ID. Intel=C2=AE Virtualization Techn= ology for Directed I/O, 5.1.8 Programming in Intel=C2=AE 64 x2APIC Mode, spec= ifies that Remapping Hardware is configured with APIC ID 31:8 in Upper Addres= s Register 31:8. This patch adopts that method and applies it to KVM_SIGNAL_MSI and GSI routes. Signed-off-by: Radim Kr=C4=8Dm=C3=A1=C5=99 --- Documentation/virtual/kvm/api.txt | 11 ++++++++++- arch/x86/kvm/irq_comm.c | 9 +++++++-- arch/x86/kvm/vmx.c | 3 ++- arch/x86/kvm/x86.c | 1 + include/uapi/linux/kvm.h | 5 +++++ virt/kvm/irqchip.c | 6 +++++- 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/= kvm/api.txt index 4d0542c5206b..07bcedc0ba09 100644 --- a/Documentation/virtual/kvm/api.txt +++ b/Documentation/virtual/kvm/api.txt @@ -1461,6 +1461,7 @@ struct kvm_irq_routing_entry { #define KVM_IRQ_ROUTING_MSI 2 #define KVM_IRQ_ROUTING_S390_ADAPTER 3 #define KVM_IRQ_ROUTING_HV_SINT 4 +#define KVM_IRQ_ROUTING_MSI_X2APIC 5 =20 No flags are specified so far, the corresponding field must be set to = zero. =20 @@ -1489,6 +1490,11 @@ struct kvm_irq_routing_hv_sint { __u32 sint; }; =20 +KVM_IRQ_ROUTING_MSI_X2APIC can be used if KVM_CAP_MSI_X2APIC is presen= t. +The entry uses struct kvm_irq_routing_msi and stores APIC ID bits 8-31= in +address_hi bits 8-31. + + 4.53 KVM_ASSIGN_SET_MSIX_NR (deprecated) =20 Capability: none @@ -2166,7 +2172,10 @@ struct kvm_msi { __u8 pad[16]; }; =20 -No flags are defined so far. The corresponding field must be 0. +Valid flags are 0 and bitwise OR of any following: +* KVM_SIGNAL_MSI_X2APIC + - valid with capability KVM_CAP_MSI_X2APIC + - address_hi bits 8-31 contain APIC ID bits 8-31 =20 =20 4.71 KVM_CREATE_PIT2 diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c index 3d17eee0987b..b9595251834b 100644 --- a/arch/x86/kvm/irq_comm.c +++ b/arch/x86/kvm/irq_comm.c @@ -117,6 +117,8 @@ void kvm_set_msi_irq(struct kvm_kernel_irq_routing_= entry *e, =20 irq->dest_id =3D (e->msi.address_lo & MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT; + if (e->type =3D=3D KVM_IRQ_ROUTING_MSI_X2APIC) + irq->dest_id |=3D MSI_ADDR_EXT_DEST_ID(e->msi.address_hi); irq->vector =3D (e->msi.data & MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT; irq->dest_mode =3D (1 << MSI_ADDR_DEST_MODE_SHIFT) & e->msi.address_l= o; @@ -150,7 +152,8 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq= _routing_entry *e, struct kvm_lapic_irq irq; int r; =20 - if (unlikely(e->type !=3D KVM_IRQ_ROUTING_MSI)) + if (unlikely(e->type !=3D KVM_IRQ_ROUTING_MSI && + e->type !=3D KVM_IRQ_ROUTING_MSI_X2APIC)) return -EWOULDBLOCK; =20 kvm_set_msi_irq(e, &irq); @@ -281,6 +284,7 @@ int kvm_set_routing_entry(struct kvm_kernel_irq_rou= ting_entry *e, goto out; break; case KVM_IRQ_ROUTING_MSI: + case KVM_IRQ_ROUTING_MSI_X2APIC: e->set =3D kvm_set_msi; e->msi.address_lo =3D ue->u.msi.address_lo; e->msi.address_hi =3D ue->u.msi.address_hi; @@ -393,7 +397,8 @@ void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, hlist_for_each_entry(entry, &table->map[i], link) { struct kvm_lapic_irq irq; =20 - if (entry->type !=3D KVM_IRQ_ROUTING_MSI) + if (entry->type !=3D KVM_IRQ_ROUTING_MSI && + entry->type !=3D KVM_IRQ_ROUTING_MSI_X2APIC) continue; =20 kvm_set_msi_irq(entry, &irq); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 133679d520af..35df8d757d1d 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -10829,7 +10829,8 @@ static int vmx_update_pi_irte(struct kvm *kvm, = unsigned int host_irq, BUG_ON(guest_irq >=3D irq_rt->nr_rt_entries); =20 hlist_for_each_entry(e, &irq_rt->map[guest_irq], link) { - if (e->type !=3D KVM_IRQ_ROUTING_MSI) + if (e->type !=3D KVM_IRQ_ROUTING_MSI && + e->type !=3D KVM_IRQ_ROUTING_MSI_X2APIC) continue; /* * VT-d PI cannot support posting multicast/broadcast diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 9b7798c7b210..86d1eb1c9d8b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2567,6 +2567,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm,= long ext) case KVM_CAP_DISABLE_QUIRKS: case KVM_CAP_SET_BOOT_CPU_ID: case KVM_CAP_SPLIT_IRQCHIP: + case KVM_CAP_MSI_X2APIC: #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT case KVM_CAP_ASSIGN_DEV_IRQ: case KVM_CAP_PCI_2_3: diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index a7f1f8032ec1..af1abec5f41d 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -865,6 +865,7 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_SPAPR_TCE_64 125 #define KVM_CAP_ARM_PMU_V3 126 #define KVM_CAP_VCPU_ATTRIBUTES 127 +#define KVM_CAP_MSI_X2APIC 128 =20 #ifdef KVM_CAP_IRQ_ROUTING =20 @@ -898,6 +899,7 @@ struct kvm_irq_routing_hv_sint { #define KVM_IRQ_ROUTING_MSI 2 #define KVM_IRQ_ROUTING_S390_ADAPTER 3 #define KVM_IRQ_ROUTING_HV_SINT 4 +#define KVM_IRQ_ROUTING_MSI_X2APIC 5 /* KVM_CAP_MSI_X2APIC */ =20 struct kvm_irq_routing_entry { __u32 gsi; @@ -1023,6 +1025,9 @@ struct kvm_one_reg { __u64 addr; }; =20 +#define KVM_SIGNAL_MSI_X2APIC (1 << 0) /* KVM_CAP_X2APIC */ +#define KVM_SIGNAL_MSI_FLAGS KVM_SIGNAL_MSI_X2APIC + struct kvm_msi { __u32 address_lo; __u32 address_hi; diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index fe84e1a95dd5..39b38b1a2156 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c @@ -62,9 +62,13 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct k= vm_msi *msi) { struct kvm_kernel_irq_routing_entry route; =20 - if (!irqchip_in_kernel(kvm) || msi->flags !=3D 0) + if (!irqchip_in_kernel(kvm) || + (msi->flags & ~KVM_SIGNAL_MSI_FLAGS) !=3D 0) return -EINVAL; =20 + /* assignment must copy kvm_set_routing_entry() */ + route.type =3D msi->flags & KVM_SIGNAL_MSI_X2APIC ? + KVM_IRQ_ROUTING_MSI_X2APIC : KVM_IRQ_ROUTING_MSI; route.msi.address_lo =3D msi->address_lo; route.msi.address_hi =3D msi->address_hi; route.msi.data =3D msi->data; --=20 2.8.2