Skip to content

Commit d4858aa

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Paolo Bonzini: "s390: - optimization for the exitless interrupt support that was merged in 4.16-rc1 - improve the branch prediction blocking for nested KVM - replace some jump tables with switch statements to improve expoline performance - fixes for multiple epoch facility ARM: - fix the interaction of userspace irqchip VMs with in-kernel irqchip VMs - make sure we can build 32-bit KVM/ARM with gcc-8. x86: - fixes for AMD SEV - fixes for Intel nested VMX, emulated UMIP and a dump_stack() on VM startup - fixes for async page fault migration - small optimization to PV TLB flush (new in 4.16-rc1) - syzkaller fixes Generic: - compiler warning fixes - syzkaller fixes - more improvements to the kvm_stat tool Two more small Spectre fixes are going to reach you via Ingo" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (40 commits) KVM: SVM: Fix SEV LAUNCH_SECRET command KVM: SVM: install RSM intercept KVM: SVM: no need to call access_ok() in LAUNCH_MEASURE command include: psp-sev: Capitalize invalid length enum crypto: ccp: Fix sparse, use plain integer as NULL pointer KVM: X86: Avoid traversing all the cpus for pv tlb flush when steal time is disabled x86/kvm: Make parse_no_xxx __init for kvm KVM: x86: fix backward migration with async_PF kvm: fix warning for non-x86 builds kvm: fix warning for CONFIG_HAVE_KVM_EVENTFD builds tools/kvm_stat: print 'Total' line for multiple events only tools/kvm_stat: group child events indented after parent tools/kvm_stat: separate drilldown and fields filtering tools/kvm_stat: eliminate extra guest/pid selection dialog tools/kvm_stat: mark private methods as such tools/kvm_stat: fix debugfs handling tools/kvm_stat: print error on invalid regex tools/kvm_stat: fix crash when filtering out all non-child trace events tools/kvm_stat: avoid 'is' for equality checks tools/kvm_stat: use a more pythonic way to iterate over dictionaries ...
2 parents 4a3928c + 9c5e0af commit d4858aa

File tree

26 files changed

+698
-516
lines changed

26 files changed

+698
-516
lines changed

Documentation/virtual/kvm/cpuid.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ KVM_FEATURE_PV_TLB_FLUSH || 9 || guest checks this feature bit
5858
|| || before enabling paravirtualized
5959
|| || tlb flush.
6060
------------------------------------------------------------------------------
61+
KVM_FEATURE_ASYNC_PF_VMEXIT || 10 || paravirtualized async PF VM exit
62+
|| || can be enabled by setting bit 2
63+
|| || when writing to msr 0x4b564d02
64+
------------------------------------------------------------------------------
6165
KVM_FEATURE_CLOCKSOURCE_STABLE_BIT || 24 || host will warn if no guest-side
6266
|| || per-cpu warps are expected in
6367
|| || kvmclock.

Documentation/virtual/kvm/msr.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ MSR_KVM_ASYNC_PF_EN: 0x4b564d02
170170
when asynchronous page faults are enabled on the vcpu 0 when
171171
disabled. Bit 1 is 1 if asynchronous page faults can be injected
172172
when vcpu is in cpl == 0. Bit 2 is 1 if asynchronous page faults
173-
are delivered to L1 as #PF vmexits.
173+
are delivered to L1 as #PF vmexits. Bit 2 can be set only if
174+
KVM_FEATURE_ASYNC_PF_VMEXIT is present in CPUID.
174175

175176
First 4 byte of 64 byte memory location will be written to by
176177
the hypervisor at the time of asynchronous page fault (APF)

arch/arm/kvm/hyp/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ ccflags-y += -fno-stack-protector -DDISABLE_BRANCH_PROFILING
77

88
KVM=../../../../virt/kvm
99

10+
CFLAGS_ARMV7VE :=$(call cc-option, -march=armv7ve)
11+
1012
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
1113
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v3-sr.o
1214
obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o
@@ -15,7 +17,10 @@ obj-$(CONFIG_KVM_ARM_HOST) += tlb.o
1517
obj-$(CONFIG_KVM_ARM_HOST) += cp15-sr.o
1618
obj-$(CONFIG_KVM_ARM_HOST) += vfp.o
1719
obj-$(CONFIG_KVM_ARM_HOST) += banked-sr.o
20+
CFLAGS_banked-sr.o += $(CFLAGS_ARMV7VE)
21+
1822
obj-$(CONFIG_KVM_ARM_HOST) += entry.o
1923
obj-$(CONFIG_KVM_ARM_HOST) += hyp-entry.o
2024
obj-$(CONFIG_KVM_ARM_HOST) += switch.o
25+
CFLAGS_switch.o += $(CFLAGS_ARMV7VE)
2126
obj-$(CONFIG_KVM_ARM_HOST) += s2-setup.o

arch/arm/kvm/hyp/banked-sr.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020

2121
#include <asm/kvm_hyp.h>
2222

23+
/*
24+
* gcc before 4.9 doesn't understand -march=armv7ve, so we have to
25+
* trick the assembler.
26+
*/
2327
__asm__(".arch_extension virt");
2428

2529
void __hyp_text __banked_save_state(struct kvm_cpu_context *ctxt)

arch/s390/kvm/intercept.c

Lines changed: 29 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,22 +22,6 @@
2222
#include "trace.h"
2323
#include "trace-s390.h"
2424

25-
26-
static const intercept_handler_t instruction_handlers[256] = {
27-
[0x01] = kvm_s390_handle_01,
28-
[0x82] = kvm_s390_handle_lpsw,
29-
[0x83] = kvm_s390_handle_diag,
30-
[0xaa] = kvm_s390_handle_aa,
31-
[0xae] = kvm_s390_handle_sigp,
32-
[0xb2] = kvm_s390_handle_b2,
33-
[0xb6] = kvm_s390_handle_stctl,
34-
[0xb7] = kvm_s390_handle_lctl,
35-
[0xb9] = kvm_s390_handle_b9,
36-
[0xe3] = kvm_s390_handle_e3,
37-
[0xe5] = kvm_s390_handle_e5,
38-
[0xeb] = kvm_s390_handle_eb,
39-
};
40-
4125
u8 kvm_s390_get_ilen(struct kvm_vcpu *vcpu)
4226
{
4327
struct kvm_s390_sie_block *sie_block = vcpu->arch.sie_block;
@@ -129,16 +113,39 @@ static int handle_validity(struct kvm_vcpu *vcpu)
129113

130114
static int handle_instruction(struct kvm_vcpu *vcpu)
131115
{
132-
intercept_handler_t handler;
133-
134116
vcpu->stat.exit_instruction++;
135117
trace_kvm_s390_intercept_instruction(vcpu,
136118
vcpu->arch.sie_block->ipa,
137119
vcpu->arch.sie_block->ipb);
138-
handler = instruction_handlers[vcpu->arch.sie_block->ipa >> 8];
139-
if (handler)
140-
return handler(vcpu);
141-
return -EOPNOTSUPP;
120+
121+
switch (vcpu->arch.sie_block->ipa >> 8) {
122+
case 0x01:
123+
return kvm_s390_handle_01(vcpu);
124+
case 0x82:
125+
return kvm_s390_handle_lpsw(vcpu);
126+
case 0x83:
127+
return kvm_s390_handle_diag(vcpu);
128+
case 0xaa:
129+
return kvm_s390_handle_aa(vcpu);
130+
case 0xae:
131+
return kvm_s390_handle_sigp(vcpu);
132+
case 0xb2:
133+
return kvm_s390_handle_b2(vcpu);
134+
case 0xb6:
135+
return kvm_s390_handle_stctl(vcpu);
136+
case 0xb7:
137+
return kvm_s390_handle_lctl(vcpu);
138+
case 0xb9:
139+
return kvm_s390_handle_b9(vcpu);
140+
case 0xe3:
141+
return kvm_s390_handle_e3(vcpu);
142+
case 0xe5:
143+
return kvm_s390_handle_e5(vcpu);
144+
case 0xeb:
145+
return kvm_s390_handle_eb(vcpu);
146+
default:
147+
return -EOPNOTSUPP;
148+
}
142149
}
143150

144151
static int inject_prog_on_prog_intercept(struct kvm_vcpu *vcpu)

arch/s390/kvm/interrupt.c

Lines changed: 79 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,15 @@ static int ckc_interrupts_enabled(struct kvm_vcpu *vcpu)
169169

170170
static int ckc_irq_pending(struct kvm_vcpu *vcpu)
171171
{
172-
if (vcpu->arch.sie_block->ckc >= kvm_s390_get_tod_clock_fast(vcpu->kvm))
172+
const u64 now = kvm_s390_get_tod_clock_fast(vcpu->kvm);
173+
const u64 ckc = vcpu->arch.sie_block->ckc;
174+
175+
if (vcpu->arch.sie_block->gcr[0] & 0x0020000000000000ul) {
176+
if ((s64)ckc >= (s64)now)
177+
return 0;
178+
} else if (ckc >= now) {
173179
return 0;
180+
}
174181
return ckc_interrupts_enabled(vcpu);
175182
}
176183

@@ -187,12 +194,6 @@ static int cpu_timer_irq_pending(struct kvm_vcpu *vcpu)
187194
return kvm_s390_get_cpu_timer(vcpu) >> 63;
188195
}
189196

190-
static inline int is_ioirq(unsigned long irq_type)
191-
{
192-
return ((irq_type >= IRQ_PEND_IO_ISC_7) &&
193-
(irq_type <= IRQ_PEND_IO_ISC_0));
194-
}
195-
196197
static uint64_t isc_to_isc_bits(int isc)
197198
{
198199
return (0x80 >> isc) << 24;
@@ -236,10 +237,15 @@ static inline int kvm_s390_gisa_tac_ipm_gisc(struct kvm_s390_gisa *gisa, u32 gis
236237
return test_and_clear_bit_inv(IPM_BIT_OFFSET + gisc, (unsigned long *) gisa);
237238
}
238239

239-
static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu)
240+
static inline unsigned long pending_irqs_no_gisa(struct kvm_vcpu *vcpu)
240241
{
241242
return vcpu->kvm->arch.float_int.pending_irqs |
242-
vcpu->arch.local_int.pending_irqs |
243+
vcpu->arch.local_int.pending_irqs;
244+
}
245+
246+
static inline unsigned long pending_irqs(struct kvm_vcpu *vcpu)
247+
{
248+
return pending_irqs_no_gisa(vcpu) |
243249
kvm_s390_gisa_get_ipm(vcpu->kvm->arch.gisa) << IRQ_PEND_IO_ISC_7;
244250
}
245251

@@ -337,7 +343,7 @@ static void __reset_intercept_indicators(struct kvm_vcpu *vcpu)
337343

338344
static void set_intercept_indicators_io(struct kvm_vcpu *vcpu)
339345
{
340-
if (!(pending_irqs(vcpu) & IRQ_PEND_IO_MASK))
346+
if (!(pending_irqs_no_gisa(vcpu) & IRQ_PEND_IO_MASK))
341347
return;
342348
else if (psw_ioint_disabled(vcpu))
343349
kvm_s390_set_cpuflags(vcpu, CPUSTAT_IO_INT);
@@ -1011,24 +1017,6 @@ static int __must_check __deliver_io(struct kvm_vcpu *vcpu,
10111017
return rc;
10121018
}
10131019

1014-
typedef int (*deliver_irq_t)(struct kvm_vcpu *vcpu);
1015-
1016-
static const deliver_irq_t deliver_irq_funcs[] = {
1017-
[IRQ_PEND_MCHK_EX] = __deliver_machine_check,
1018-
[IRQ_PEND_MCHK_REP] = __deliver_machine_check,
1019-
[IRQ_PEND_PROG] = __deliver_prog,
1020-
[IRQ_PEND_EXT_EMERGENCY] = __deliver_emergency_signal,
1021-
[IRQ_PEND_EXT_EXTERNAL] = __deliver_external_call,
1022-
[IRQ_PEND_EXT_CLOCK_COMP] = __deliver_ckc,
1023-
[IRQ_PEND_EXT_CPU_TIMER] = __deliver_cpu_timer,
1024-
[IRQ_PEND_RESTART] = __deliver_restart,
1025-
[IRQ_PEND_SET_PREFIX] = __deliver_set_prefix,
1026-
[IRQ_PEND_PFAULT_INIT] = __deliver_pfault_init,
1027-
[IRQ_PEND_EXT_SERVICE] = __deliver_service,
1028-
[IRQ_PEND_PFAULT_DONE] = __deliver_pfault_done,
1029-
[IRQ_PEND_VIRTIO] = __deliver_virtio,
1030-
};
1031-
10321020
/* Check whether an external call is pending (deliverable or not) */
10331021
int kvm_s390_ext_call_pending(struct kvm_vcpu *vcpu)
10341022
{
@@ -1066,13 +1054,19 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu)
10661054

10671055
static u64 __calculate_sltime(struct kvm_vcpu *vcpu)
10681056
{
1069-
u64 now, cputm, sltime = 0;
1057+
const u64 now = kvm_s390_get_tod_clock_fast(vcpu->kvm);
1058+
const u64 ckc = vcpu->arch.sie_block->ckc;
1059+
u64 cputm, sltime = 0;
10701060

10711061
if (ckc_interrupts_enabled(vcpu)) {
1072-
now = kvm_s390_get_tod_clock_fast(vcpu->kvm);
1073-
sltime = tod_to_ns(vcpu->arch.sie_block->ckc - now);
1074-
/* already expired or overflow? */
1075-
if (!sltime || vcpu->arch.sie_block->ckc <= now)
1062+
if (vcpu->arch.sie_block->gcr[0] & 0x0020000000000000ul) {
1063+
if ((s64)now < (s64)ckc)
1064+
sltime = tod_to_ns((s64)ckc - (s64)now);
1065+
} else if (now < ckc) {
1066+
sltime = tod_to_ns(ckc - now);
1067+
}
1068+
/* already expired */
1069+
if (!sltime)
10761070
return 0;
10771071
if (cpu_timer_interrupts_enabled(vcpu)) {
10781072
cputm = kvm_s390_get_cpu_timer(vcpu);
@@ -1192,7 +1186,6 @@ void kvm_s390_clear_local_irqs(struct kvm_vcpu *vcpu)
11921186
int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
11931187
{
11941188
struct kvm_s390_local_interrupt *li = &vcpu->arch.local_int;
1195-
deliver_irq_t func;
11961189
int rc = 0;
11971190
unsigned long irq_type;
11981191
unsigned long irqs;
@@ -1212,16 +1205,57 @@ int __must_check kvm_s390_deliver_pending_interrupts(struct kvm_vcpu *vcpu)
12121205
while ((irqs = deliverable_irqs(vcpu)) && !rc) {
12131206
/* bits are in the reverse order of interrupt priority */
12141207
irq_type = find_last_bit(&irqs, IRQ_PEND_COUNT);
1215-
if (is_ioirq(irq_type)) {
1208+
switch (irq_type) {
1209+
case IRQ_PEND_IO_ISC_0:
1210+
case IRQ_PEND_IO_ISC_1:
1211+
case IRQ_PEND_IO_ISC_2:
1212+
case IRQ_PEND_IO_ISC_3:
1213+
case IRQ_PEND_IO_ISC_4:
1214+
case IRQ_PEND_IO_ISC_5:
1215+
case IRQ_PEND_IO_ISC_6:
1216+
case IRQ_PEND_IO_ISC_7:
12161217
rc = __deliver_io(vcpu, irq_type);
1217-
} else {
1218-
func = deliver_irq_funcs[irq_type];
1219-
if (!func) {
1220-
WARN_ON_ONCE(func == NULL);
1221-
clear_bit(irq_type, &li->pending_irqs);
1222-
continue;
1223-
}
1224-
rc = func(vcpu);
1218+
break;
1219+
case IRQ_PEND_MCHK_EX:
1220+
case IRQ_PEND_MCHK_REP:
1221+
rc = __deliver_machine_check(vcpu);
1222+
break;
1223+
case IRQ_PEND_PROG:
1224+
rc = __deliver_prog(vcpu);
1225+
break;
1226+
case IRQ_PEND_EXT_EMERGENCY:
1227+
rc = __deliver_emergency_signal(vcpu);
1228+
break;
1229+
case IRQ_PEND_EXT_EXTERNAL:
1230+
rc = __deliver_external_call(vcpu);
1231+
break;
1232+
case IRQ_PEND_EXT_CLOCK_COMP:
1233+
rc = __deliver_ckc(vcpu);
1234+
break;
1235+
case IRQ_PEND_EXT_CPU_TIMER:
1236+
rc = __deliver_cpu_timer(vcpu);
1237+
break;
1238+
case IRQ_PEND_RESTART:
1239+
rc = __deliver_restart(vcpu);
1240+
break;
1241+
case IRQ_PEND_SET_PREFIX:
1242+
rc = __deliver_set_prefix(vcpu);
1243+
break;
1244+
case IRQ_PEND_PFAULT_INIT:
1245+
rc = __deliver_pfault_init(vcpu);
1246+
break;
1247+
case IRQ_PEND_EXT_SERVICE:
1248+
rc = __deliver_service(vcpu);
1249+
break;
1250+
case IRQ_PEND_PFAULT_DONE:
1251+
rc = __deliver_pfault_done(vcpu);
1252+
break;
1253+
case IRQ_PEND_VIRTIO:
1254+
rc = __deliver_virtio(vcpu);
1255+
break;
1256+
default:
1257+
WARN_ONCE(1, "Unknown pending irq type %ld", irq_type);
1258+
clear_bit(irq_type, &li->pending_irqs);
12251259
}
12261260
}
12271261

@@ -1701,7 +1735,8 @@ static void __floating_irq_kick(struct kvm *kvm, u64 type)
17011735
kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_STOP_INT);
17021736
break;
17031737
case KVM_S390_INT_IO_MIN...KVM_S390_INT_IO_MAX:
1704-
kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_IO_INT);
1738+
if (!(type & KVM_S390_INT_IO_AI_MASK && kvm->arch.gisa))
1739+
kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_IO_INT);
17051740
break;
17061741
default:
17071742
kvm_s390_set_cpuflags(dst_vcpu, CPUSTAT_EXT_INT);

0 commit comments

Comments
 (0)