]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - arch/s390/kvm/kvm-s390.c
mmap locking API: use coccinelle to convert mmap_sem rwsem call sites
[mirror_ubuntu-jammy-kernel.git] / arch / s390 / kvm / kvm-s390.c
index d05bb040fd427c1b25e1c9693930aa2ec01f0412..d0ff26d157bcb7aeb00a9000d58c61c6db6b6e44 100644 (file)
 #include <linux/bitmap.h>
 #include <linux/sched/signal.h>
 #include <linux/string.h>
+#include <linux/pgtable.h>
 
 #include <asm/asm-offsets.h>
 #include <asm/lowcore.h>
 #include <asm/stp.h>
-#include <asm/pgtable.h>
 #include <asm/gmap.h>
 #include <asm/nmi.h>
 #include <asm/switch_to.h>
 #define VCPU_IRQS_MAX_BUF (sizeof(struct kvm_s390_irq) * \
                           (KVM_MAX_VCPUS + LOCAL_IRQS))
 
-#define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU
-#define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM
-
 struct kvm_stats_debugfs_item debugfs_entries[] = {
-       { "userspace_handled", VCPU_STAT(exit_userspace) },
-       { "exit_null", VCPU_STAT(exit_null) },
-       { "exit_validity", VCPU_STAT(exit_validity) },
-       { "exit_stop_request", VCPU_STAT(exit_stop_request) },
-       { "exit_external_request", VCPU_STAT(exit_external_request) },
-       { "exit_io_request", VCPU_STAT(exit_io_request) },
-       { "exit_external_interrupt", VCPU_STAT(exit_external_interrupt) },
-       { "exit_instruction", VCPU_STAT(exit_instruction) },
-       { "exit_pei", VCPU_STAT(exit_pei) },
-       { "exit_program_interruption", VCPU_STAT(exit_program_interruption) },
-       { "exit_instr_and_program_int", VCPU_STAT(exit_instr_and_program) },
-       { "exit_operation_exception", VCPU_STAT(exit_operation_exception) },
-       { "halt_successful_poll", VCPU_STAT(halt_successful_poll) },
-       { "halt_attempted_poll", VCPU_STAT(halt_attempted_poll) },
-       { "halt_poll_invalid", VCPU_STAT(halt_poll_invalid) },
-       { "halt_no_poll_steal", VCPU_STAT(halt_no_poll_steal) },
-       { "halt_wakeup", VCPU_STAT(halt_wakeup) },
-       { "instruction_lctlg", VCPU_STAT(instruction_lctlg) },
-       { "instruction_lctl", VCPU_STAT(instruction_lctl) },
-       { "instruction_stctl", VCPU_STAT(instruction_stctl) },
-       { "instruction_stctg", VCPU_STAT(instruction_stctg) },
-       { "deliver_ckc", VCPU_STAT(deliver_ckc) },
-       { "deliver_cputm", VCPU_STAT(deliver_cputm) },
-       { "deliver_emergency_signal", VCPU_STAT(deliver_emergency_signal) },
-       { "deliver_external_call", VCPU_STAT(deliver_external_call) },
-       { "deliver_service_signal", VCPU_STAT(deliver_service_signal) },
-       { "deliver_virtio", VCPU_STAT(deliver_virtio) },
-       { "deliver_stop_signal", VCPU_STAT(deliver_stop_signal) },
-       { "deliver_prefix_signal", VCPU_STAT(deliver_prefix_signal) },
-       { "deliver_restart_signal", VCPU_STAT(deliver_restart_signal) },
-       { "deliver_program", VCPU_STAT(deliver_program) },
-       { "deliver_io", VCPU_STAT(deliver_io) },
-       { "deliver_machine_check", VCPU_STAT(deliver_machine_check) },
-       { "exit_wait_state", VCPU_STAT(exit_wait_state) },
-       { "inject_ckc", VCPU_STAT(inject_ckc) },
-       { "inject_cputm", VCPU_STAT(inject_cputm) },
-       { "inject_external_call", VCPU_STAT(inject_external_call) },
-       { "inject_float_mchk", VM_STAT(inject_float_mchk) },
-       { "inject_emergency_signal", VCPU_STAT(inject_emergency_signal) },
-       { "inject_io", VM_STAT(inject_io) },
-       { "inject_mchk", VCPU_STAT(inject_mchk) },
-       { "inject_pfault_done", VM_STAT(inject_pfault_done) },
-       { "inject_program", VCPU_STAT(inject_program) },
-       { "inject_restart", VCPU_STAT(inject_restart) },
-       { "inject_service_signal", VM_STAT(inject_service_signal) },
-       { "inject_set_prefix", VCPU_STAT(inject_set_prefix) },
-       { "inject_stop_signal", VCPU_STAT(inject_stop_signal) },
-       { "inject_pfault_init", VCPU_STAT(inject_pfault_init) },
-       { "inject_virtio", VM_STAT(inject_virtio) },
-       { "instruction_epsw", VCPU_STAT(instruction_epsw) },
-       { "instruction_gs", VCPU_STAT(instruction_gs) },
-       { "instruction_io_other", VCPU_STAT(instruction_io_other) },
-       { "instruction_lpsw", VCPU_STAT(instruction_lpsw) },
-       { "instruction_lpswe", VCPU_STAT(instruction_lpswe) },
-       { "instruction_pfmf", VCPU_STAT(instruction_pfmf) },
-       { "instruction_ptff", VCPU_STAT(instruction_ptff) },
-       { "instruction_stidp", VCPU_STAT(instruction_stidp) },
-       { "instruction_sck", VCPU_STAT(instruction_sck) },
-       { "instruction_sckpf", VCPU_STAT(instruction_sckpf) },
-       { "instruction_spx", VCPU_STAT(instruction_spx) },
-       { "instruction_stpx", VCPU_STAT(instruction_stpx) },
-       { "instruction_stap", VCPU_STAT(instruction_stap) },
-       { "instruction_iske", VCPU_STAT(instruction_iske) },
-       { "instruction_ri", VCPU_STAT(instruction_ri) },
-       { "instruction_rrbe", VCPU_STAT(instruction_rrbe) },
-       { "instruction_sske", VCPU_STAT(instruction_sske) },
-       { "instruction_ipte_interlock", VCPU_STAT(instruction_ipte_interlock) },
-       { "instruction_essa", VCPU_STAT(instruction_essa) },
-       { "instruction_stsi", VCPU_STAT(instruction_stsi) },
-       { "instruction_stfl", VCPU_STAT(instruction_stfl) },
-       { "instruction_tb", VCPU_STAT(instruction_tb) },
-       { "instruction_tpi", VCPU_STAT(instruction_tpi) },
-       { "instruction_tprot", VCPU_STAT(instruction_tprot) },
-       { "instruction_tsch", VCPU_STAT(instruction_tsch) },
-       { "instruction_sthyi", VCPU_STAT(instruction_sthyi) },
-       { "instruction_sie", VCPU_STAT(instruction_sie) },
-       { "instruction_sigp_sense", VCPU_STAT(instruction_sigp_sense) },
-       { "instruction_sigp_sense_running", VCPU_STAT(instruction_sigp_sense_running) },
-       { "instruction_sigp_external_call", VCPU_STAT(instruction_sigp_external_call) },
-       { "instruction_sigp_emergency", VCPU_STAT(instruction_sigp_emergency) },
-       { "instruction_sigp_cond_emergency", VCPU_STAT(instruction_sigp_cond_emergency) },
-       { "instruction_sigp_start", VCPU_STAT(instruction_sigp_start) },
-       { "instruction_sigp_stop", VCPU_STAT(instruction_sigp_stop) },
-       { "instruction_sigp_stop_store_status", VCPU_STAT(instruction_sigp_stop_store_status) },
-       { "instruction_sigp_store_status", VCPU_STAT(instruction_sigp_store_status) },
-       { "instruction_sigp_store_adtl_status", VCPU_STAT(instruction_sigp_store_adtl_status) },
-       { "instruction_sigp_set_arch", VCPU_STAT(instruction_sigp_arch) },
-       { "instruction_sigp_set_prefix", VCPU_STAT(instruction_sigp_prefix) },
-       { "instruction_sigp_restart", VCPU_STAT(instruction_sigp_restart) },
-       { "instruction_sigp_cpu_reset", VCPU_STAT(instruction_sigp_cpu_reset) },
-       { "instruction_sigp_init_cpu_reset", VCPU_STAT(instruction_sigp_init_cpu_reset) },
-       { "instruction_sigp_unknown", VCPU_STAT(instruction_sigp_unknown) },
-       { "instruction_diag_10", VCPU_STAT(diagnose_10) },
-       { "instruction_diag_44", VCPU_STAT(diagnose_44) },
-       { "instruction_diag_9c", VCPU_STAT(diagnose_9c) },
-       { "diag_9c_ignored", VCPU_STAT(diagnose_9c_ignored) },
-       { "instruction_diag_258", VCPU_STAT(diagnose_258) },
-       { "instruction_diag_308", VCPU_STAT(diagnose_308) },
-       { "instruction_diag_500", VCPU_STAT(diagnose_500) },
-       { "instruction_diag_other", VCPU_STAT(diagnose_other) },
+       VCPU_STAT("userspace_handled", exit_userspace),
+       VCPU_STAT("exit_null", exit_null),
+       VCPU_STAT("exit_validity", exit_validity),
+       VCPU_STAT("exit_stop_request", exit_stop_request),
+       VCPU_STAT("exit_external_request", exit_external_request),
+       VCPU_STAT("exit_io_request", exit_io_request),
+       VCPU_STAT("exit_external_interrupt", exit_external_interrupt),
+       VCPU_STAT("exit_instruction", exit_instruction),
+       VCPU_STAT("exit_pei", exit_pei),
+       VCPU_STAT("exit_program_interruption", exit_program_interruption),
+       VCPU_STAT("exit_instr_and_program_int", exit_instr_and_program),
+       VCPU_STAT("exit_operation_exception", exit_operation_exception),
+       VCPU_STAT("halt_successful_poll", halt_successful_poll),
+       VCPU_STAT("halt_attempted_poll", halt_attempted_poll),
+       VCPU_STAT("halt_poll_invalid", halt_poll_invalid),
+       VCPU_STAT("halt_no_poll_steal", halt_no_poll_steal),
+       VCPU_STAT("halt_wakeup", halt_wakeup),
+       VCPU_STAT("halt_poll_success_ns", halt_poll_success_ns),
+       VCPU_STAT("halt_poll_fail_ns", halt_poll_fail_ns),
+       VCPU_STAT("instruction_lctlg", instruction_lctlg),
+       VCPU_STAT("instruction_lctl", instruction_lctl),
+       VCPU_STAT("instruction_stctl", instruction_stctl),
+       VCPU_STAT("instruction_stctg", instruction_stctg),
+       VCPU_STAT("deliver_ckc", deliver_ckc),
+       VCPU_STAT("deliver_cputm", deliver_cputm),
+       VCPU_STAT("deliver_emergency_signal", deliver_emergency_signal),
+       VCPU_STAT("deliver_external_call", deliver_external_call),
+       VCPU_STAT("deliver_service_signal", deliver_service_signal),
+       VCPU_STAT("deliver_virtio", deliver_virtio),
+       VCPU_STAT("deliver_stop_signal", deliver_stop_signal),
+       VCPU_STAT("deliver_prefix_signal", deliver_prefix_signal),
+       VCPU_STAT("deliver_restart_signal", deliver_restart_signal),
+       VCPU_STAT("deliver_program", deliver_program),
+       VCPU_STAT("deliver_io", deliver_io),
+       VCPU_STAT("deliver_machine_check", deliver_machine_check),
+       VCPU_STAT("exit_wait_state", exit_wait_state),
+       VCPU_STAT("inject_ckc", inject_ckc),
+       VCPU_STAT("inject_cputm", inject_cputm),
+       VCPU_STAT("inject_external_call", inject_external_call),
+       VM_STAT("inject_float_mchk", inject_float_mchk),
+       VCPU_STAT("inject_emergency_signal", inject_emergency_signal),
+       VM_STAT("inject_io", inject_io),
+       VCPU_STAT("inject_mchk", inject_mchk),
+       VM_STAT("inject_pfault_done", inject_pfault_done),
+       VCPU_STAT("inject_program", inject_program),
+       VCPU_STAT("inject_restart", inject_restart),
+       VM_STAT("inject_service_signal", inject_service_signal),
+       VCPU_STAT("inject_set_prefix", inject_set_prefix),
+       VCPU_STAT("inject_stop_signal", inject_stop_signal),
+       VCPU_STAT("inject_pfault_init", inject_pfault_init),
+       VM_STAT("inject_virtio", inject_virtio),
+       VCPU_STAT("instruction_epsw", instruction_epsw),
+       VCPU_STAT("instruction_gs", instruction_gs),
+       VCPU_STAT("instruction_io_other", instruction_io_other),
+       VCPU_STAT("instruction_lpsw", instruction_lpsw),
+       VCPU_STAT("instruction_lpswe", instruction_lpswe),
+       VCPU_STAT("instruction_pfmf", instruction_pfmf),
+       VCPU_STAT("instruction_ptff", instruction_ptff),
+       VCPU_STAT("instruction_stidp", instruction_stidp),
+       VCPU_STAT("instruction_sck", instruction_sck),
+       VCPU_STAT("instruction_sckpf", instruction_sckpf),
+       VCPU_STAT("instruction_spx", instruction_spx),
+       VCPU_STAT("instruction_stpx", instruction_stpx),
+       VCPU_STAT("instruction_stap", instruction_stap),
+       VCPU_STAT("instruction_iske", instruction_iske),
+       VCPU_STAT("instruction_ri", instruction_ri),
+       VCPU_STAT("instruction_rrbe", instruction_rrbe),
+       VCPU_STAT("instruction_sske", instruction_sske),
+       VCPU_STAT("instruction_ipte_interlock", instruction_ipte_interlock),
+       VCPU_STAT("instruction_essa", instruction_essa),
+       VCPU_STAT("instruction_stsi", instruction_stsi),
+       VCPU_STAT("instruction_stfl", instruction_stfl),
+       VCPU_STAT("instruction_tb", instruction_tb),
+       VCPU_STAT("instruction_tpi", instruction_tpi),
+       VCPU_STAT("instruction_tprot", instruction_tprot),
+       VCPU_STAT("instruction_tsch", instruction_tsch),
+       VCPU_STAT("instruction_sthyi", instruction_sthyi),
+       VCPU_STAT("instruction_sie", instruction_sie),
+       VCPU_STAT("instruction_sigp_sense", instruction_sigp_sense),
+       VCPU_STAT("instruction_sigp_sense_running", instruction_sigp_sense_running),
+       VCPU_STAT("instruction_sigp_external_call", instruction_sigp_external_call),
+       VCPU_STAT("instruction_sigp_emergency", instruction_sigp_emergency),
+       VCPU_STAT("instruction_sigp_cond_emergency", instruction_sigp_cond_emergency),
+       VCPU_STAT("instruction_sigp_start", instruction_sigp_start),
+       VCPU_STAT("instruction_sigp_stop", instruction_sigp_stop),
+       VCPU_STAT("instruction_sigp_stop_store_status", instruction_sigp_stop_store_status),
+       VCPU_STAT("instruction_sigp_store_status", instruction_sigp_store_status),
+       VCPU_STAT("instruction_sigp_store_adtl_status", instruction_sigp_store_adtl_status),
+       VCPU_STAT("instruction_sigp_set_arch", instruction_sigp_arch),
+       VCPU_STAT("instruction_sigp_set_prefix", instruction_sigp_prefix),
+       VCPU_STAT("instruction_sigp_restart", instruction_sigp_restart),
+       VCPU_STAT("instruction_sigp_cpu_reset", instruction_sigp_cpu_reset),
+       VCPU_STAT("instruction_sigp_init_cpu_reset", instruction_sigp_init_cpu_reset),
+       VCPU_STAT("instruction_sigp_unknown", instruction_sigp_unknown),
+       VCPU_STAT("instruction_diag_10", diagnose_10),
+       VCPU_STAT("instruction_diag_44", diagnose_44),
+       VCPU_STAT("instruction_diag_9c", diagnose_9c),
+       VCPU_STAT("diag_9c_ignored", diagnose_9c_ignored),
+       VCPU_STAT("instruction_diag_258", diagnose_258),
+       VCPU_STAT("instruction_diag_308", diagnose_308),
+       VCPU_STAT("instruction_diag_500", diagnose_500),
+       VCPU_STAT("instruction_diag_other", diagnose_other),
        { NULL }
 };
 
@@ -764,9 +763,9 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap)
                        r = -EINVAL;
                else {
                        r = 0;
-                       down_write(&kvm->mm->mmap_sem);
+                       mmap_write_lock(kvm->mm);
                        kvm->mm->context.allow_gmap_hpage_1m = 1;
-                       up_write(&kvm->mm->mmap_sem);
+                       mmap_write_unlock(kvm->mm);
                        /*
                         * We might have to create fake 4k page
                         * tables. To avoid that the hardware works on
@@ -1816,7 +1815,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
        if (!keys)
                return -ENOMEM;
 
-       down_read(&current->mm->mmap_sem);
+       mmap_read_lock(current->mm);
        srcu_idx = srcu_read_lock(&kvm->srcu);
        for (i = 0; i < args->count; i++) {
                hva = gfn_to_hva(kvm, args->start_gfn + i);
@@ -1830,7 +1829,7 @@ static long kvm_s390_get_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
                        break;
        }
        srcu_read_unlock(&kvm->srcu, srcu_idx);
-       up_read(&current->mm->mmap_sem);
+       mmap_read_unlock(current->mm);
 
        if (!r) {
                r = copy_to_user((uint8_t __user *)args->skeydata_addr, keys,
@@ -1874,7 +1873,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
                goto out;
 
        i = 0;
-       down_read(&current->mm->mmap_sem);
+       mmap_read_lock(current->mm);
        srcu_idx = srcu_read_lock(&kvm->srcu);
         while (i < args->count) {
                unlocked = false;
@@ -1901,7 +1900,7 @@ static long kvm_s390_set_skeys(struct kvm *kvm, struct kvm_s390_skeys *args)
                        i++;
        }
        srcu_read_unlock(&kvm->srcu, srcu_idx);
-       up_read(&current->mm->mmap_sem);
+       mmap_read_unlock(current->mm);
 out:
        kvfree(keys);
        return r;
@@ -2090,14 +2089,14 @@ static int kvm_s390_get_cmma_bits(struct kvm *kvm,
        if (!values)
                return -ENOMEM;
 
-       down_read(&kvm->mm->mmap_sem);
+       mmap_read_lock(kvm->mm);
        srcu_idx = srcu_read_lock(&kvm->srcu);
        if (peek)
                ret = kvm_s390_peek_cmma(kvm, args, values, bufsize);
        else
                ret = kvm_s390_get_cmma(kvm, args, values, bufsize);
        srcu_read_unlock(&kvm->srcu, srcu_idx);
-       up_read(&kvm->mm->mmap_sem);
+       mmap_read_unlock(kvm->mm);
 
        if (kvm->arch.migration_mode)
                args->remaining = atomic64_read(&kvm->arch.cmma_dirty_pages);
@@ -2147,7 +2146,7 @@ static int kvm_s390_set_cmma_bits(struct kvm *kvm,
                goto out;
        }
 
-       down_read(&kvm->mm->mmap_sem);
+       mmap_read_lock(kvm->mm);
        srcu_idx = srcu_read_lock(&kvm->srcu);
        for (i = 0; i < args->count; i++) {
                hva = gfn_to_hva(kvm, args->start_gfn + i);
@@ -2162,12 +2161,12 @@ static int kvm_s390_set_cmma_bits(struct kvm *kvm,
                set_pgste_bits(kvm->mm, hva, mask, pgstev);
        }
        srcu_read_unlock(&kvm->srcu, srcu_idx);
-       up_read(&kvm->mm->mmap_sem);
+       mmap_read_unlock(kvm->mm);
 
        if (!kvm->mm->context.uses_cmm) {
-               down_write(&kvm->mm->mmap_sem);
+               mmap_write_lock(kvm->mm);
                kvm->mm->context.uses_cmm = 1;
-               up_write(&kvm->mm->mmap_sem);
+               mmap_write_unlock(kvm->mm);
        }
 out:
        vfree(bits);
@@ -2240,9 +2239,9 @@ static int kvm_s390_handle_pv(struct kvm *kvm, struct kvm_pv_cmd *cmd)
                if (r)
                        break;
 
-               down_write(&current->mm->mmap_sem);
+               mmap_write_lock(current->mm);
                r = gmap_mark_unmergeable();
-               up_write(&current->mm->mmap_sem);
+               mmap_write_unlock(current->mm);
                if (r)
                        break;
 
@@ -3944,7 +3943,7 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu,
        /* s390 will always inject the page directly */
 }
 
-bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu)
+bool kvm_arch_can_dequeue_async_page_present(struct kvm_vcpu *vcpu)
 {
        /*
         * s390 will always inject the page directly,
@@ -3999,9 +3998,6 @@ static int vcpu_pre_run(struct kvm_vcpu *vcpu)
        if (need_resched())
                schedule();
 
-       if (test_cpu_flag(CIF_MCCK_PENDING))
-               s390_handle_mcck();
-
        if (!kvm_is_ucontrol(vcpu->kvm)) {
                rc = kvm_s390_deliver_pending_interrupts(vcpu);
                if (rc)
@@ -4337,8 +4333,9 @@ static void store_regs(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
                store_regs_fmt2(vcpu, kvm_run);
 }
 
-int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
+int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
 {
+       struct kvm_run *kvm_run = vcpu->run;
        int rc;
 
        if (kvm_run->immediate_exit)