mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 10:04:04 +02:00
Merge branch 'kvm-6.15-rc2-fixes' into HEAD
This commit is contained in:
commit
b6262dd695
|
|
@ -1472,8 +1472,13 @@ struct kvm_arch {
|
|||
struct once nx_once;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/* The number of TDP MMU pages across all roots. */
|
||||
#ifdef CONFIG_KVM_PROVE_MMU
|
||||
/*
|
||||
* The number of TDP MMU pages across all roots. Used only to sanity
|
||||
* check that KVM isn't leaking TDP MMU pages.
|
||||
*/
|
||||
atomic64_t tdp_mmu_pages;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* List of struct kvm_mmu_pages being used as roots.
|
||||
|
|
|
|||
|
|
@ -1427,8 +1427,8 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
|
|||
}
|
||||
break;
|
||||
case 0xa: { /* Architectural Performance Monitoring */
|
||||
union cpuid10_eax eax;
|
||||
union cpuid10_edx edx;
|
||||
union cpuid10_eax eax = { };
|
||||
union cpuid10_edx edx = { };
|
||||
|
||||
if (!enable_pmu || !static_cpu_has(X86_FEATURE_ARCH_PERFMON)) {
|
||||
entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
|
||||
|
|
@ -1444,8 +1444,6 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
|
|||
|
||||
if (kvm_pmu_cap.version)
|
||||
edx.split.anythread_deprecated = 1;
|
||||
edx.split.reserved1 = 0;
|
||||
edx.split.reserved2 = 0;
|
||||
|
||||
entry->eax = eax.full;
|
||||
entry->ebx = kvm_pmu_cap.events_mask;
|
||||
|
|
@ -1763,7 +1761,7 @@ static inline int __do_cpuid_func(struct kvm_cpuid_array *array, u32 function)
|
|||
break;
|
||||
/* AMD Extended Performance Monitoring and Debug */
|
||||
case 0x80000022: {
|
||||
union cpuid_0x80000022_ebx ebx;
|
||||
union cpuid_0x80000022_ebx ebx = { };
|
||||
|
||||
entry->ecx = entry->edx = 0;
|
||||
if (!enable_pmu || !kvm_cpu_cap_has(X86_FEATURE_PERFMON_V2)) {
|
||||
|
|
|
|||
|
|
@ -40,7 +40,9 @@ void kvm_mmu_uninit_tdp_mmu(struct kvm *kvm)
|
|||
kvm_tdp_mmu_invalidate_roots(kvm, KVM_VALID_ROOTS);
|
||||
kvm_tdp_mmu_zap_invalidated_roots(kvm, false);
|
||||
|
||||
WARN_ON(atomic64_read(&kvm->arch.tdp_mmu_pages));
|
||||
#ifdef CONFIG_KVM_PROVE_MMU
|
||||
KVM_MMU_WARN_ON(atomic64_read(&kvm->arch.tdp_mmu_pages));
|
||||
#endif
|
||||
WARN_ON(!list_empty(&kvm->arch.tdp_mmu_roots));
|
||||
|
||||
/*
|
||||
|
|
@ -325,13 +327,17 @@ static void handle_changed_spte(struct kvm *kvm, int as_id, gfn_t gfn,
|
|||
static void tdp_account_mmu_page(struct kvm *kvm, struct kvm_mmu_page *sp)
|
||||
{
|
||||
kvm_account_pgtable_pages((void *)sp->spt, +1);
|
||||
#ifdef CONFIG_KVM_PROVE_MMU
|
||||
atomic64_inc(&kvm->arch.tdp_mmu_pages);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void tdp_unaccount_mmu_page(struct kvm *kvm, struct kvm_mmu_page *sp)
|
||||
{
|
||||
kvm_account_pgtable_pages((void *)sp->spt, -1);
|
||||
#ifdef CONFIG_KVM_PROVE_MMU
|
||||
atomic64_dec(&kvm->arch.tdp_mmu_pages);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -11786,6 +11786,8 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
|
|||
if (kvm_mpx_supported())
|
||||
kvm_load_guest_fpu(vcpu);
|
||||
|
||||
kvm_vcpu_srcu_read_lock(vcpu);
|
||||
|
||||
r = kvm_apic_accept_events(vcpu);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
|
@ -11799,6 +11801,8 @@ int kvm_arch_vcpu_ioctl_get_mpstate(struct kvm_vcpu *vcpu,
|
|||
mp_state->mp_state = vcpu->arch.mp_state;
|
||||
|
||||
out:
|
||||
kvm_vcpu_srcu_read_unlock(vcpu);
|
||||
|
||||
if (kvm_mpx_supported())
|
||||
kvm_put_guest_fpu(vcpu);
|
||||
vcpu_put(vcpu);
|
||||
|
|
|
|||
|
|
@ -2382,7 +2382,7 @@ static inline bool kvm_is_visible_memslot(struct kvm_memory_slot *memslot)
|
|||
struct kvm_vcpu *kvm_get_running_vcpu(void);
|
||||
struct kvm_vcpu * __percpu *kvm_get_running_vcpus(void);
|
||||
|
||||
#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
|
||||
#if IS_ENABLED(CONFIG_HAVE_KVM_IRQ_BYPASS)
|
||||
bool kvm_arch_has_irq_bypass(void);
|
||||
int kvm_arch_irq_bypass_add_producer(struct irq_bypass_consumer *,
|
||||
struct irq_bypass_producer *);
|
||||
|
|
|
|||
|
|
@ -196,25 +196,27 @@ static void calc_min_max_cpu(void)
|
|||
static void help(const char *name)
|
||||
{
|
||||
puts("");
|
||||
printf("usage: %s [-h] [-u]\n", name);
|
||||
printf("usage: %s [-h] [-u] [-l latency]\n", name);
|
||||
printf(" -u: Don't sanity check the number of successful KVM_RUNs\n");
|
||||
printf(" -l: Set /dev/cpu_dma_latency to suppress deep sleep states\n");
|
||||
puts("");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int r, i, snapshot, opt, fd = -1, latency = -1;
|
||||
bool skip_sanity_check = false;
|
||||
int r, i, snapshot;
|
||||
struct kvm_vm *vm;
|
||||
struct kvm_vcpu *vcpu;
|
||||
u32 cpu, rseq_cpu;
|
||||
int opt;
|
||||
|
||||
while ((opt = getopt(argc, argv, "hu")) != -1) {
|
||||
while ((opt = getopt(argc, argv, "hl:u")) != -1) {
|
||||
switch (opt) {
|
||||
case 'u':
|
||||
skip_sanity_check = true;
|
||||
case 'l':
|
||||
latency = atoi_paranoid(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
|
|
@ -243,6 +245,20 @@ int main(int argc, char *argv[])
|
|||
pthread_create(&migration_thread, NULL, migration_worker,
|
||||
(void *)(unsigned long)syscall(SYS_gettid));
|
||||
|
||||
if (latency >= 0) {
|
||||
/*
|
||||
* Writes to cpu_dma_latency persist only while the file is
|
||||
* open, i.e. it allows userspace to provide guaranteed latency
|
||||
* while running a workload. Keep the file open until the test
|
||||
* completes, otherwise writing cpu_dma_latency is meaningless.
|
||||
*/
|
||||
fd = open("/dev/cpu_dma_latency", O_RDWR);
|
||||
TEST_ASSERT(fd >= 0, __KVM_SYSCALL_ERROR("open() /dev/cpu_dma_latency", fd));
|
||||
|
||||
r = write(fd, &latency, 4);
|
||||
TEST_ASSERT(r >= 1, "Error setting /dev/cpu_dma_latency");
|
||||
}
|
||||
|
||||
for (i = 0; !done; i++) {
|
||||
vcpu_run(vcpu);
|
||||
TEST_ASSERT(get_ucall(vcpu, NULL) == UCALL_SYNC,
|
||||
|
|
@ -278,6 +294,9 @@ int main(int argc, char *argv[])
|
|||
"rseq CPU = %d, sched CPU = %d", rseq_cpu, cpu);
|
||||
}
|
||||
|
||||
if (fd > 0)
|
||||
close(fd);
|
||||
|
||||
/*
|
||||
* Sanity check that the test was able to enter the guest a reasonable
|
||||
* number of times, e.g. didn't get stalled too often/long waiting for
|
||||
|
|
@ -293,8 +312,8 @@ int main(int argc, char *argv[])
|
|||
TEST_ASSERT(skip_sanity_check || i > (NR_TASK_MIGRATIONS / 2),
|
||||
"Only performed %d KVM_RUNs, task stalled too much?\n\n"
|
||||
" Try disabling deep sleep states to reduce CPU wakeup latency,\n"
|
||||
" e.g. via cpuidle.off=1 or setting /dev/cpu_dma_latency to '0',\n"
|
||||
" or run with -u to disable this sanity check.", i);
|
||||
" e.g. via cpuidle.off=1 or via -l <latency>, or run with -u to\n"
|
||||
" disable this sanity check.", i);
|
||||
|
||||
pthread_join(migration_thread, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ config KVM_COMPAT
|
|||
depends on KVM && COMPAT && !(S390 || ARM64 || RISCV)
|
||||
|
||||
config HAVE_KVM_IRQ_BYPASS
|
||||
bool
|
||||
tristate
|
||||
select IRQ_BYPASS_MANAGER
|
||||
|
||||
config HAVE_KVM_VCPU_ASYNC_IOCTL
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ irqfd_shutdown(struct work_struct *work)
|
|||
/*
|
||||
* It is now safe to release the object's resources
|
||||
*/
|
||||
#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
|
||||
#if IS_ENABLED(CONFIG_HAVE_KVM_IRQ_BYPASS)
|
||||
irq_bypass_unregister_consumer(&irqfd->consumer);
|
||||
#endif
|
||||
eventfd_ctx_put(irqfd->eventfd);
|
||||
|
|
@ -274,7 +274,7 @@ static void irqfd_update(struct kvm *kvm, struct kvm_kernel_irqfd *irqfd)
|
|||
write_seqcount_end(&irqfd->irq_entry_sc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
|
||||
#if IS_ENABLED(CONFIG_HAVE_KVM_IRQ_BYPASS)
|
||||
void __attribute__((weak)) kvm_arch_irq_bypass_stop(
|
||||
struct irq_bypass_consumer *cons)
|
||||
{
|
||||
|
|
@ -424,7 +424,7 @@ kvm_irqfd_assign(struct kvm *kvm, struct kvm_irqfd *args)
|
|||
if (events & EPOLLIN)
|
||||
schedule_work(&irqfd->inject);
|
||||
|
||||
#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
|
||||
#if IS_ENABLED(CONFIG_HAVE_KVM_IRQ_BYPASS)
|
||||
if (kvm_arch_has_irq_bypass()) {
|
||||
irqfd->consumer.token = (void *)irqfd->eventfd;
|
||||
irqfd->consumer.add_producer = kvm_arch_irq_bypass_add_producer;
|
||||
|
|
@ -609,14 +609,14 @@ void kvm_irq_routing_update(struct kvm *kvm)
|
|||
spin_lock_irq(&kvm->irqfds.lock);
|
||||
|
||||
list_for_each_entry(irqfd, &kvm->irqfds.items, list) {
|
||||
#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
|
||||
#if IS_ENABLED(CONFIG_HAVE_KVM_IRQ_BYPASS)
|
||||
/* Under irqfds.lock, so can read irq_entry safely */
|
||||
struct kvm_kernel_irq_routing_entry old = irqfd->irq_entry;
|
||||
#endif
|
||||
|
||||
irqfd_update(kvm, irqfd);
|
||||
|
||||
#ifdef CONFIG_HAVE_KVM_IRQ_BYPASS
|
||||
#if IS_ENABLED(CONFIG_HAVE_KVM_IRQ_BYPASS)
|
||||
if (irqfd->producer &&
|
||||
kvm_arch_irqfd_route_changed(&old, &irqfd->irq_entry)) {
|
||||
int ret = kvm_arch_update_irqfd_routing(
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user