aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRadim Krčmář <rkrcmar@redhat.com>2016-07-12 16:09:27 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2016-07-14 03:03:57 -0400
commit3713131345fbea291cbd859d248e06ed77815962 (patch)
treefb712d5c0b49b53984a3b01d0df29c7dfee62e4e
parentc63cf538eb4bf6a5ffd3750366d8d56f023645a5 (diff)
KVM: x86: add KVM_CAP_X2APIC_API
KVM_CAP_X2APIC_API is a capability for features related to x2APIC enablement. KVM_X2APIC_API_32BIT_FORMAT feature can be enabled to extend APIC ID in get/set ioctl and MSI addresses to 32 bits. Both are needed to support x2APIC. The feature has to be enableable and disabled by default, because get/set ioctl shifted and truncated APIC ID to 8 bits by using a non-standard protocol inspired by xAPIC and the change is not backward-compatible. Changes to MSI addresses follow the format used by interrupt remapping unit. The upper address word, that used to be 0, contains upper 24 bits of the LAPIC address in its upper 24 bits. Lower 8 bits are reserved as 0. Using the upper address word is not backward-compatible either as we didn't check that userspace zeroed the word. Reserved bits are still not explicitly checked, but non-zero data will affect LAPIC addresses, which will cause a bug. Signed-off-by: Radim Krčmář <rkrcmar@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--Documentation/virtual/kvm/api.txt41
-rw-r--r--arch/x86/include/asm/kvm_host.h4
-rw-r--r--arch/x86/kvm/irq_comm.c29
-rw-r--r--arch/x86/kvm/lapic.c13
-rw-r--r--arch/x86/kvm/vmx.c2
-rw-r--r--arch/x86/kvm/x86.c15
-rw-r--r--include/trace/events/kvm.h5
-rw-r--r--include/uapi/linux/kvm.h3
8 files changed, 99 insertions, 13 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 09efa9eb3926..e34e51fa28b0 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1482,6 +1482,11 @@ struct kvm_irq_routing_msi {
1482 __u32 pad; 1482 __u32 pad;
1483}; 1483};
1484 1484
1485On x86, address_hi is ignored unless the KVM_X2APIC_API_USE_32BIT_IDS
1486feature of KVM_CAP_X2APIC_API capability is enabled. If it is enabled,
1487address_hi bits 31-8 provide bits 31-8 of the destination id. Bits 7-0 of
1488address_hi must be zero.
1489
1485struct kvm_irq_routing_s390_adapter { 1490struct kvm_irq_routing_s390_adapter {
1486 __u64 ind_addr; 1491 __u64 ind_addr;
1487 __u64 summary_addr; 1492 __u64 summary_addr;
@@ -1583,6 +1588,17 @@ struct kvm_lapic_state {
1583Reads the Local APIC registers and copies them into the input argument. The 1588Reads the Local APIC registers and copies them into the input argument. The
1584data format and layout are the same as documented in the architecture manual. 1589data format and layout are the same as documented in the architecture manual.
1585 1590
1591If KVM_X2APIC_API_USE_32BIT_IDS feature of KVM_CAP_X2APIC_API is
1592enabled, then the format of APIC_ID register depends on the APIC mode
1593(reported by MSR_IA32_APICBASE) of its VCPU. x2APIC stores APIC ID in
1594the APIC_ID register (bytes 32-35). xAPIC only allows an 8-bit APIC ID
1595which is stored in bits 31-24 of the APIC register, or equivalently in
1596byte 35 of struct kvm_lapic_state's regs field. KVM_GET_LAPIC must then
1597be called after MSR_IA32_APICBASE has been set with KVM_SET_MSR.
1598
1599If KVM_X2APIC_API_USE_32BIT_IDS feature is disabled, struct kvm_lapic_state
1600always uses xAPIC format.
1601
1586 1602
15874.58 KVM_SET_LAPIC 16034.58 KVM_SET_LAPIC
1588 1604
@@ -1600,6 +1616,10 @@ struct kvm_lapic_state {
1600Copies the input argument into the Local APIC registers. The data format 1616Copies the input argument into the Local APIC registers. The data format
1601and layout are the same as documented in the architecture manual. 1617and layout are the same as documented in the architecture manual.
1602 1618
1619The format of the APIC ID register (bytes 32-35 of struct kvm_lapic_state's
1620regs field) depends on the state of the KVM_CAP_X2APIC_API capability.
1621See the note in KVM_GET_LAPIC.
1622
1603 1623
16044.59 KVM_IOEVENTFD 16244.59 KVM_IOEVENTFD
1605 1625
@@ -2180,6 +2200,10 @@ struct kvm_msi {
2180 2200
2181No flags are defined so far. The corresponding field must be 0. 2201No flags are defined so far. The corresponding field must be 0.
2182 2202
2203On x86, address_hi is ignored unless the KVM_CAP_X2APIC_API capability is
2204enabled. If it is enabled, address_hi bits 31-8 provide bits 31-8 of the
2205destination id. Bits 7-0 of address_hi must be zero.
2206
2183 2207
21844.71 KVM_CREATE_PIT2 22084.71 KVM_CREATE_PIT2
2185 2209
@@ -3811,6 +3835,23 @@ Allows use of runtime-instrumentation introduced with zEC12 processor.
3811Will return -EINVAL if the machine does not support runtime-instrumentation. 3835Will return -EINVAL if the machine does not support runtime-instrumentation.
3812Will return -EBUSY if a VCPU has already been created. 3836Will return -EBUSY if a VCPU has already been created.
3813 3837
38387.7 KVM_CAP_X2APIC_API
3839
3840Architectures: x86
3841Parameters: args[0] - features that should be enabled
3842Returns: 0 on success, -EINVAL when args[0] contains invalid features
3843
3844Valid feature flags in args[0] are
3845
3846#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
3847
3848Enabling KVM_X2APIC_API_USE_32BIT_IDS changes the behavior of
3849KVM_SET_GSI_ROUTING, KVM_SIGNAL_MSI, KVM_SET_LAPIC, and KVM_GET_LAPIC,
3850allowing the use of 32-bit APIC IDs. See KVM_CAP_X2APIC_API in their
3851respective sections.
3852
3853
3854
38148. Other capabilities. 38558. Other capabilities.
3815---------------------- 3856----------------------
3816 3857
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index a2832cc3cb81..7c00ba3242d7 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -782,6 +782,8 @@ struct kvm_arch {
782 u32 ldr_mode; 782 u32 ldr_mode;
783 struct page *avic_logical_id_table_page; 783 struct page *avic_logical_id_table_page;
784 struct page *avic_physical_id_table_page; 784 struct page *avic_physical_id_table_page;
785
786 bool x2apic_format;
785}; 787};
786 788
787struct kvm_vm_stat { 789struct kvm_vm_stat {
@@ -1364,7 +1366,7 @@ bool kvm_vcpu_is_bsp(struct kvm_vcpu *vcpu);
1364bool kvm_intr_is_single_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq, 1366bool kvm_intr_is_single_vcpu(struct kvm *kvm, struct kvm_lapic_irq *irq,
1365 struct kvm_vcpu **dest_vcpu); 1367 struct kvm_vcpu **dest_vcpu);
1366 1368
1367void kvm_set_msi_irq(struct kvm_kernel_irq_routing_entry *e, 1369void kvm_set_msi_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e,
1368 struct kvm_lapic_irq *irq); 1370 struct kvm_lapic_irq *irq);
1369 1371
1370static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) 1372static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu)
diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
index 889563d50c55..25810b144b58 100644
--- a/arch/x86/kvm/irq_comm.c
+++ b/arch/x86/kvm/irq_comm.c
@@ -110,13 +110,17 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src,
110 return r; 110 return r;
111} 111}
112 112
113void kvm_set_msi_irq(struct kvm_kernel_irq_routing_entry *e, 113void kvm_set_msi_irq(struct kvm *kvm, struct kvm_kernel_irq_routing_entry *e,
114 struct kvm_lapic_irq *irq) 114 struct kvm_lapic_irq *irq)
115{ 115{
116 trace_kvm_msi_set_irq(e->msi.address_lo, e->msi.data); 116 trace_kvm_msi_set_irq(e->msi.address_lo | (kvm->arch.x2apic_format ?
117 (u64)e->msi.address_hi << 32 : 0),
118 e->msi.data);
117 119
118 irq->dest_id = (e->msi.address_lo & 120 irq->dest_id = (e->msi.address_lo &
119 MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT; 121 MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SHIFT;
122 if (kvm->arch.x2apic_format)
123 irq->dest_id |= MSI_ADDR_EXT_DEST_ID(e->msi.address_hi);
120 irq->vector = (e->msi.data & 124 irq->vector = (e->msi.data &
121 MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT; 125 MSI_DATA_VECTOR_MASK) >> MSI_DATA_VECTOR_SHIFT;
122 irq->dest_mode = (1 << MSI_ADDR_DEST_MODE_SHIFT) & e->msi.address_lo; 126 irq->dest_mode = (1 << MSI_ADDR_DEST_MODE_SHIFT) & e->msi.address_lo;
@@ -129,15 +133,24 @@ void kvm_set_msi_irq(struct kvm_kernel_irq_routing_entry *e,
129} 133}
130EXPORT_SYMBOL_GPL(kvm_set_msi_irq); 134EXPORT_SYMBOL_GPL(kvm_set_msi_irq);
131 135
136static inline bool kvm_msi_route_invalid(struct kvm *kvm,
137 struct kvm_kernel_irq_routing_entry *e)
138{
139 return kvm->arch.x2apic_format && (e->msi.address_hi & 0xff);
140}
141
132int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, 142int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e,
133 struct kvm *kvm, int irq_source_id, int level, bool line_status) 143 struct kvm *kvm, int irq_source_id, int level, bool line_status)
134{ 144{
135 struct kvm_lapic_irq irq; 145 struct kvm_lapic_irq irq;
136 146
147 if (kvm_msi_route_invalid(kvm, e))
148 return -EINVAL;
149
137 if (!level) 150 if (!level)
138 return -1; 151 return -1;
139 152
140 kvm_set_msi_irq(e, &irq); 153 kvm_set_msi_irq(kvm, e, &irq);
141 154
142 return kvm_irq_delivery_to_apic(kvm, NULL, &irq, NULL); 155 return kvm_irq_delivery_to_apic(kvm, NULL, &irq, NULL);
143} 156}
@@ -153,7 +166,10 @@ int kvm_arch_set_irq_inatomic(struct kvm_kernel_irq_routing_entry *e,
153 if (unlikely(e->type != KVM_IRQ_ROUTING_MSI)) 166 if (unlikely(e->type != KVM_IRQ_ROUTING_MSI))
154 return -EWOULDBLOCK; 167 return -EWOULDBLOCK;
155 168
156 kvm_set_msi_irq(e, &irq); 169 if (kvm_msi_route_invalid(kvm, e))
170 return -EINVAL;
171
172 kvm_set_msi_irq(kvm, e, &irq);
157 173
158 if (kvm_irq_delivery_to_apic_fast(kvm, NULL, &irq, &r, NULL)) 174 if (kvm_irq_delivery_to_apic_fast(kvm, NULL, &irq, &r, NULL))
159 return r; 175 return r;
@@ -286,6 +302,9 @@ int kvm_set_routing_entry(struct kvm *kvm,
286 e->msi.address_lo = ue->u.msi.address_lo; 302 e->msi.address_lo = ue->u.msi.address_lo;
287 e->msi.address_hi = ue->u.msi.address_hi; 303 e->msi.address_hi = ue->u.msi.address_hi;
288 e->msi.data = ue->u.msi.data; 304 e->msi.data = ue->u.msi.data;
305
306 if (kvm_msi_route_invalid(kvm, e))
307 goto out;
289 break; 308 break;
290 case KVM_IRQ_ROUTING_HV_SINT: 309 case KVM_IRQ_ROUTING_HV_SINT:
291 e->set = kvm_hv_set_sint; 310 e->set = kvm_hv_set_sint;
@@ -394,7 +413,7 @@ void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu,
394 if (entry->type != KVM_IRQ_ROUTING_MSI) 413 if (entry->type != KVM_IRQ_ROUTING_MSI)
395 continue; 414 continue;
396 415
397 kvm_set_msi_irq(entry, &irq); 416 kvm_set_msi_irq(vcpu->kvm, entry, &irq);
398 417
399 if (irq.level && kvm_apic_match_dest(vcpu, NULL, 0, 418 if (irq.level && kvm_apic_match_dest(vcpu, NULL, 0,
400 irq.dest_id, irq.dest_mode)) 419 irq.dest_id, irq.dest_mode))
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index 3c2a8c113054..d27a7829a4ce 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1991,10 +1991,15 @@ static int kvm_apic_state_fixup(struct kvm_vcpu *vcpu,
1991 if (apic_x2apic_mode(vcpu->arch.apic)) { 1991 if (apic_x2apic_mode(vcpu->arch.apic)) {
1992 u32 *id = (u32 *)(s->regs + APIC_ID); 1992 u32 *id = (u32 *)(s->regs + APIC_ID);
1993 1993
1994 if (set) 1994 if (vcpu->kvm->arch.x2apic_format) {
1995 *id >>= 24; 1995 if (*id != vcpu->vcpu_id)
1996 else 1996 return -EINVAL;
1997 *id <<= 24; 1997 } else {
1998 if (set)
1999 *id >>= 24;
2000 else
2001 *id <<= 24;
2002 }
1998 } 2003 }
1999 2004
2000 return 0; 2005 return 0;
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 7bdd6b1a2373..b61cdadf8623 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -11104,7 +11104,7 @@ static int vmx_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
11104 * We will support full lowest-priority interrupt later. 11104 * We will support full lowest-priority interrupt later.
11105 */ 11105 */
11106 11106
11107 kvm_set_msi_irq(e, &irq); 11107 kvm_set_msi_irq(kvm, e, &irq);
11108 if (!kvm_intr_is_single_vcpu(kvm, &irq, &vcpu)) { 11108 if (!kvm_intr_is_single_vcpu(kvm, &irq, &vcpu)) {
11109 /* 11109 /*
11110 * Make sure the IRTE is in remapped mode if 11110 * Make sure the IRTE is in remapped mode if
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index b6e402d16e0c..d86f563a6896 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -90,6 +90,8 @@ static u64 __read_mostly efer_reserved_bits = ~((u64)EFER_SCE);
90#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM 90#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
91#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU 91#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
92 92
93#define KVM_X2APIC_API_VALID_FLAGS (KVM_X2APIC_API_USE_32BIT_IDS)
94
93static void update_cr8_intercept(struct kvm_vcpu *vcpu); 95static void update_cr8_intercept(struct kvm_vcpu *vcpu);
94static void process_nmi(struct kvm_vcpu *vcpu); 96static void process_nmi(struct kvm_vcpu *vcpu);
95static void enter_smm(struct kvm_vcpu *vcpu); 97static void enter_smm(struct kvm_vcpu *vcpu);
@@ -2625,6 +2627,9 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
2625 case KVM_CAP_TSC_CONTROL: 2627 case KVM_CAP_TSC_CONTROL:
2626 r = kvm_has_tsc_control; 2628 r = kvm_has_tsc_control;
2627 break; 2629 break;
2630 case KVM_CAP_X2APIC_API:
2631 r = KVM_X2APIC_API_VALID_FLAGS;
2632 break;
2628 default: 2633 default:
2629 r = 0; 2634 r = 0;
2630 break; 2635 break;
@@ -3799,6 +3804,16 @@ split_irqchip_unlock:
3799 mutex_unlock(&kvm->lock); 3804 mutex_unlock(&kvm->lock);
3800 break; 3805 break;
3801 } 3806 }
3807 case KVM_CAP_X2APIC_API:
3808 r = -EINVAL;
3809 if (cap->args[0] & ~KVM_X2APIC_API_VALID_FLAGS)
3810 break;
3811
3812 if (cap->args[0] & KVM_X2APIC_API_USE_32BIT_IDS)
3813 kvm->arch.x2apic_format = true;
3814
3815 r = 0;
3816 break;
3802 default: 3817 default:
3803 r = -EINVAL; 3818 r = -EINVAL;
3804 break; 3819 break;
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
index f28292d73ddb..8ade3eb6c640 100644
--- a/include/trace/events/kvm.h
+++ b/include/trace/events/kvm.h
@@ -151,8 +151,9 @@ TRACE_EVENT(kvm_msi_set_irq,
151 __entry->data = data; 151 __entry->data = data;
152 ), 152 ),
153 153
154 TP_printk("dst %u vec %u (%s|%s|%s%s)", 154 TP_printk("dst %llx vec %u (%s|%s|%s%s)",
155 (u8)(__entry->address >> 12), (u8)__entry->data, 155 (u8)(__entry->address >> 12) | ((__entry->address >> 32) & 0xffffff00),
156 (u8)__entry->data,
156 __print_symbolic((__entry->data >> 8 & 0x7), kvm_deliver_mode), 157 __print_symbolic((__entry->data >> 8 & 0x7), kvm_deliver_mode),
157 (__entry->address & (1<<2)) ? "logical" : "physical", 158 (__entry->address & (1<<2)) ? "logical" : "physical",
158 (__entry->data & (1<<15)) ? "level" : "edge", 159 (__entry->data & (1<<15)) ? "level" : "edge",
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 05ebf475104c..f704403e19a0 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -866,6 +866,7 @@ struct kvm_ppc_smmu_info {
866#define KVM_CAP_ARM_PMU_V3 126 866#define KVM_CAP_ARM_PMU_V3 126
867#define KVM_CAP_VCPU_ATTRIBUTES 127 867#define KVM_CAP_VCPU_ATTRIBUTES 127
868#define KVM_CAP_MAX_VCPU_ID 128 868#define KVM_CAP_MAX_VCPU_ID 128
869#define KVM_CAP_X2APIC_API 129
869 870
870#ifdef KVM_CAP_IRQ_ROUTING 871#ifdef KVM_CAP_IRQ_ROUTING
871 872
@@ -1313,4 +1314,6 @@ struct kvm_assigned_msix_entry {
1313 __u16 padding[3]; 1314 __u16 padding[3];
1314}; 1315};
1315 1316
1317#define KVM_X2APIC_API_USE_32BIT_IDS (1ULL << 0)
1318
1316#endif /* __LINUX_KVM_H */ 1319#endif /* __LINUX_KVM_H */