Skip to content

Commit 867583b

Browse files
committed
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm fixes from Paolo Bonzini: "RISC-V: - Fix a race condition in updating external interrupt for trap-n-emulated IMSIC swfile - Fix print_reg defaults in get-reg-list selftest ARM: - Ensure a vCPU's redistributor is unregistered from the MMIO bus if vCPU creation fails - Fix building KVM selftests for arm64 from the top-level Makefile x86: - Fix breakage for SEV-ES guests that use XSAVES Selftests: - Fix bad use of strcat(), by not using strcat() at all" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: SEV: Do not intercept accesses to MSR_IA32_XSS for SEV-ES guests KVM: selftests: Fix dynamic generation of configuration names RISCV: KVM: update external interrupt atomically for IMSIC swfile KVM: riscv: selftests: Fix get-reg-list print_reg defaults KVM: selftests: Ensure sysreg-defs.h is generated at the expected path KVM: Convert comment into an assertion in kvm_io_bus_register_dev() KVM: arm64: vgic: Ensure that slots_lock is held in vgic_register_all_redist_iodevs() KVM: arm64: vgic: Force vcpu vgic teardown on vcpu destroy KVM: arm64: vgic: Add a non-locking primitive for kvm_vgic_vcpu_destroy() KVM: arm64: vgic: Simplify kvm_vgic_destroy()
2 parents c0f65a7 + ef5b283 commit 867583b

File tree

12 files changed

+97
-40
lines changed

12 files changed

+97
-40
lines changed

arch/arm64/kvm/arm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
410410
kvm_mmu_free_memory_cache(&vcpu->arch.mmu_page_cache);
411411
kvm_timer_vcpu_terminate(vcpu);
412412
kvm_pmu_vcpu_destroy(vcpu);
413-
413+
kvm_vgic_vcpu_destroy(vcpu);
414414
kvm_arm_vcpu_destroy(vcpu);
415415
}
416416

arch/arm64/kvm/vgic/vgic-init.c

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm)
368368
vgic_v4_teardown(kvm);
369369
}
370370

371-
void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
371+
static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
372372
{
373373
struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
374374

@@ -379,29 +379,39 @@ void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
379379
vgic_flush_pending_lpis(vcpu);
380380

381381
INIT_LIST_HEAD(&vgic_cpu->ap_list_head);
382-
vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
382+
if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) {
383+
vgic_unregister_redist_iodev(vcpu);
384+
vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF;
385+
}
383386
}
384387

385-
static void __kvm_vgic_destroy(struct kvm *kvm)
388+
void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu)
389+
{
390+
struct kvm *kvm = vcpu->kvm;
391+
392+
mutex_lock(&kvm->slots_lock);
393+
__kvm_vgic_vcpu_destroy(vcpu);
394+
mutex_unlock(&kvm->slots_lock);
395+
}
396+
397+
void kvm_vgic_destroy(struct kvm *kvm)
386398
{
387399
struct kvm_vcpu *vcpu;
388400
unsigned long i;
389401

390-
lockdep_assert_held(&kvm->arch.config_lock);
402+
mutex_lock(&kvm->slots_lock);
391403

392404
vgic_debug_destroy(kvm);
393405

394406
kvm_for_each_vcpu(i, vcpu, kvm)
395-
kvm_vgic_vcpu_destroy(vcpu);
407+
__kvm_vgic_vcpu_destroy(vcpu);
408+
409+
mutex_lock(&kvm->arch.config_lock);
396410

397411
kvm_vgic_dist_destroy(kvm);
398-
}
399412

400-
void kvm_vgic_destroy(struct kvm *kvm)
401-
{
402-
mutex_lock(&kvm->arch.config_lock);
403-
__kvm_vgic_destroy(kvm);
404413
mutex_unlock(&kvm->arch.config_lock);
414+
mutex_unlock(&kvm->slots_lock);
405415
}
406416

407417
/**
@@ -469,25 +479,26 @@ int kvm_vgic_map_resources(struct kvm *kvm)
469479
type = VGIC_V3;
470480
}
471481

472-
if (ret) {
473-
__kvm_vgic_destroy(kvm);
482+
if (ret)
474483
goto out;
475-
}
484+
476485
dist->ready = true;
477486
dist_base = dist->vgic_dist_base;
478487
mutex_unlock(&kvm->arch.config_lock);
479488

480489
ret = vgic_register_dist_iodev(kvm, dist_base, type);
481-
if (ret) {
490+
if (ret)
482491
kvm_err("Unable to register VGIC dist MMIO regions\n");
483-
kvm_vgic_destroy(kvm);
484-
}
485-
mutex_unlock(&kvm->slots_lock);
486-
return ret;
487492

493+
goto out_slots;
488494
out:
489495
mutex_unlock(&kvm->arch.config_lock);
496+
out_slots:
490497
mutex_unlock(&kvm->slots_lock);
498+
499+
if (ret)
500+
kvm_vgic_destroy(kvm);
501+
491502
return ret;
492503
}
493504

arch/arm64/kvm/vgic/vgic-mmio-v3.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,7 @@ int vgic_register_redist_iodev(struct kvm_vcpu *vcpu)
820820
return ret;
821821
}
822822

823-
static void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu)
823+
void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu)
824824
{
825825
struct vgic_io_device *rd_dev = &vcpu->arch.vgic_cpu.rd_iodev;
826826

@@ -833,6 +833,8 @@ static int vgic_register_all_redist_iodevs(struct kvm *kvm)
833833
unsigned long c;
834834
int ret = 0;
835835

836+
lockdep_assert_held(&kvm->slots_lock);
837+
836838
kvm_for_each_vcpu(c, vcpu, kvm) {
837839
ret = vgic_register_redist_iodev(vcpu);
838840
if (ret)

arch/arm64/kvm/vgic/vgic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ int vgic_v3_lpi_sync_pending_status(struct kvm *kvm, struct vgic_irq *irq);
241241
int vgic_v3_save_pending_tables(struct kvm *kvm);
242242
int vgic_v3_set_redist_base(struct kvm *kvm, u32 index, u64 addr, u32 count);
243243
int vgic_register_redist_iodev(struct kvm_vcpu *vcpu);
244+
void vgic_unregister_redist_iodev(struct kvm_vcpu *vcpu);
244245
bool vgic_v3_check_base(struct kvm *kvm);
245246

246247
void vgic_v3_load(struct kvm_vcpu *vcpu);

arch/riscv/kvm/aia_imsic.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct imsic {
5555
/* IMSIC SW-file */
5656
struct imsic_mrif *swfile;
5757
phys_addr_t swfile_pa;
58+
spinlock_t swfile_extirq_lock;
5859
};
5960

6061
#define imsic_vs_csr_read(__c) \
@@ -613,12 +614,23 @@ static void imsic_swfile_extirq_update(struct kvm_vcpu *vcpu)
613614
{
614615
struct imsic *imsic = vcpu->arch.aia_context.imsic_state;
615616
struct imsic_mrif *mrif = imsic->swfile;
617+
unsigned long flags;
618+
619+
/*
620+
* The critical section is necessary during external interrupt
621+
* updates to avoid the risk of losing interrupts due to potential
622+
* interruptions between reading topei and updating pending status.
623+
*/
624+
625+
spin_lock_irqsave(&imsic->swfile_extirq_lock, flags);
616626

617627
if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) &&
618628
imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis))
619629
kvm_riscv_vcpu_set_interrupt(vcpu, IRQ_VS_EXT);
620630
else
621631
kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT);
632+
633+
spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags);
622634
}
623635

624636
static void imsic_swfile_read(struct kvm_vcpu *vcpu, bool clear,
@@ -1039,6 +1051,7 @@ int kvm_riscv_vcpu_aia_imsic_init(struct kvm_vcpu *vcpu)
10391051
}
10401052
imsic->swfile = page_to_virt(swfile_page);
10411053
imsic->swfile_pa = page_to_phys(swfile_page);
1054+
spin_lock_init(&imsic->swfile_extirq_lock);
10421055

10431056
/* Setup IO device */
10441057
kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops);

arch/x86/kvm/svm/sev.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,6 +2972,25 @@ static void sev_es_vcpu_after_set_cpuid(struct vcpu_svm *svm)
29722972

29732973
set_msr_interception(vcpu, svm->msrpm, MSR_TSC_AUX, v_tsc_aux, v_tsc_aux);
29742974
}
2975+
2976+
/*
2977+
* For SEV-ES, accesses to MSR_IA32_XSS should not be intercepted if
2978+
* the host/guest supports its use.
2979+
*
2980+
* guest_can_use() checks a number of requirements on the host/guest to
2981+
* ensure that MSR_IA32_XSS is available, but it might report true even
2982+
* if X86_FEATURE_XSAVES isn't configured in the guest to ensure host
2983+
* MSR_IA32_XSS is always properly restored. For SEV-ES, it is better
2984+
* to further check that the guest CPUID actually supports
2985+
* X86_FEATURE_XSAVES so that accesses to MSR_IA32_XSS by misbehaved
2986+
* guests will still get intercepted and caught in the normal
2987+
* kvm_emulate_rdmsr()/kvm_emulated_wrmsr() paths.
2988+
*/
2989+
if (guest_can_use(vcpu, X86_FEATURE_XSAVES) &&
2990+
guest_cpuid_has(vcpu, X86_FEATURE_XSAVES))
2991+
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_XSS, 1, 1);
2992+
else
2993+
set_msr_interception(vcpu, svm->msrpm, MSR_IA32_XSS, 0, 0);
29752994
}
29762995

29772996
void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm)

arch/x86/kvm/svm/svm.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ static const struct svm_direct_access_msrs {
103103
{ .index = MSR_IA32_LASTBRANCHTOIP, .always = false },
104104
{ .index = MSR_IA32_LASTINTFROMIP, .always = false },
105105
{ .index = MSR_IA32_LASTINTTOIP, .always = false },
106+
{ .index = MSR_IA32_XSS, .always = false },
106107
{ .index = MSR_EFER, .always = false },
107108
{ .index = MSR_IA32_CR_PAT, .always = false },
108109
{ .index = MSR_AMD64_SEV_ES_GHCB, .always = true },

arch/x86/kvm/svm/svm.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
#define IOPM_SIZE PAGE_SIZE * 3
3131
#define MSRPM_SIZE PAGE_SIZE * 2
3232

33-
#define MAX_DIRECT_ACCESS_MSRS 46
33+
#define MAX_DIRECT_ACCESS_MSRS 47
3434
#define MSRPM_OFFSETS 32
3535
extern u32 msrpm_offsets[MSRPM_OFFSETS] __read_mostly;
3636
extern bool npt_enabled;

tools/testing/selftests/kvm/Makefile

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,6 @@ else
1717
ARCH_DIR := $(ARCH)
1818
endif
1919

20-
ifeq ($(ARCH),arm64)
21-
tools_dir := $(top_srcdir)/tools
22-
arm64_tools_dir := $(tools_dir)/arch/arm64/tools/
23-
GEN_HDRS := $(top_srcdir)/tools/arch/arm64/include/generated/
24-
CFLAGS += -I$(GEN_HDRS)
25-
26-
$(GEN_HDRS): $(wildcard $(arm64_tools_dir)/*)
27-
$(MAKE) -C $(arm64_tools_dir) O=$(tools_dir)
28-
endif
29-
3020
LIBKVM += lib/assert.c
3121
LIBKVM += lib/elf.c
3222
LIBKVM += lib/guest_modes.c
@@ -234,6 +224,22 @@ CFLAGS += -Wall -Wstrict-prototypes -Wuninitialized -O2 -g -std=gnu99 \
234224
ifeq ($(ARCH),s390)
235225
CFLAGS += -march=z10
236226
endif
227+
ifeq ($(ARCH),arm64)
228+
tools_dir := $(top_srcdir)/tools
229+
arm64_tools_dir := $(tools_dir)/arch/arm64/tools/
230+
231+
ifneq ($(abs_objdir),)
232+
arm64_hdr_outdir := $(abs_objdir)/tools/
233+
else
234+
arm64_hdr_outdir := $(tools_dir)/
235+
endif
236+
237+
GEN_HDRS := $(arm64_hdr_outdir)arch/arm64/include/generated/
238+
CFLAGS += -I$(GEN_HDRS)
239+
240+
$(GEN_HDRS): $(wildcard $(arm64_tools_dir)/*)
241+
$(MAKE) -C $(arm64_tools_dir) OUTPUT=$(arm64_hdr_outdir)
242+
endif
237243

238244
no-pie-option := $(call try-run, echo 'int main(void) { return 0; }' | \
239245
$(CC) -Werror $(CFLAGS) -no-pie -x c - -o "$$TMP", -no-pie)

tools/testing/selftests/kvm/get-reg-list.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,12 @@ static const char *config_name(struct vcpu_reg_list *c)
7171
for_each_sublist(c, s) {
7272
if (!strcmp(s->name, "base"))
7373
continue;
74-
strcat(c->name + len, s->name);
75-
len += strlen(s->name) + 1;
76-
c->name[len - 1] = '+';
74+
if (len)
75+
c->name[len++] = '+';
76+
strcpy(c->name + len, s->name);
77+
len += strlen(s->name);
7778
}
78-
c->name[len - 1] = '\0';
79+
c->name[len] = '\0';
7980

8081
return c->name;
8182
}

0 commit comments

Comments
 (0)