1. 25 Mar, 2020 1 commit
    • Catalin Marinas's avatar
      Merge branches 'for-next/memory-hotremove', 'for-next/arm_sdei',... · da12d273
      Catalin Marinas authored
      Merge branches 'for-next/memory-hotremove', 'for-next/arm_sdei', 'for-next/amu', 'for-next/final-cap-helper', 'for-next/cpu_ops-cleanup', 'for-next/misc' and 'for-next/perf' into for-next/core
      
      * for-next/memory-hotremove:
        : Memory hot-remove support for arm64
        arm64/mm: Enable memory hot remove
        arm64/mm: Hold memory hotplug lock while walking for kernel page table dump
      
      * for-next/arm_sdei:
        : SDEI: fix double locking on return from hibernate and clean-up
        firmware: arm_sdei: clean up sdei_event_create()
        firmware: arm_sdei: Use cpus_read_lock() to avoid races with cpuhp
        firmware: arm_sdei: fix possible double-lock on hibernate error path
        firmware: arm_sdei: fix double-lock on hibernate with shared events
      
      * for-next/amu:
        : ARMv8.4 Activity Monitors support
        clocksource/drivers/arm_arch_timer: validate arch_timer_rate
        arm64: use activity monitors for frequency invariance
        cpufreq: add function to get the hardware max frequency
        Documentation: arm64: document support for the AMU extension
        arm64/kvm: disable access to AMU registers from kvm guests
        arm64: trap to EL1 accesses to AMU counters from EL0
        arm64: add support for the AMU extension v1
      
      * for-next/final-cap-helper:
        : Introduce cpus_have_final_cap_helper(), migrate arm64 KVM to it
        arm64: kvm: hyp: use cpus_have_final_cap()
        arm64: cpufeature: add cpus_have_final_cap()
      
      * for-next/cpu_ops-cleanup:
        : cpu_ops[] access code clean-up
        arm64: Introduce get_cpu_ops() helper function
        arm64: Rename cpu_read_ops() to init_cpu_ops()
        arm64: Declare ACPI parking protocol CPU operation if needed
      
      * for-next/misc:
        : Various fixes and clean-ups
        arm64: define __alloc_zeroed_user_highpage
        arm64/kernel: Simplify __cpu_up() by bailing out early
        arm64: remove redundant blank for '=' operator
        arm64: kexec_file: Fixed code style.
        arm64: add blank after 'if'
        arm64: fix spelling mistake "ca not" -> "cannot"
        arm64: entry: unmask IRQ in el0_sp()
        arm64: efi: add efi-entry.o to targets instead of extra-$(CONFIG_EFI)
        arm64: csum: Optimise IPv6 header checksum
        arch/arm64: fix typo in a comment
        arm64: remove gratuitious/stray .ltorg stanzas
        arm64: Update comment for ASID() macro
        arm64: mm: convert cpu_do_switch_mm() to C
        arm64: fix NUMA Kconfig typos
      
      * for-next/perf:
        : arm64 perf updates
        arm64: perf: Add support for ARMv8.5-PMU 64-bit counters
        KVM: arm64: limit PMU version to PMUv3 for ARMv8.1
        arm64: cpufeature: Extract capped perfmon fields
        arm64: perf: Clean up enable/disable calls
        perf: arm-ccn: Use scnprintf() for robustness
        arm64: perf: Support new DT compatibles
        arm64: perf: Refactor PMU init callbacks
        perf: arm_spe: Remove unnecessary zero check on 'nr_pages'
      da12d273
  2. 24 Mar, 2020 3 commits
  3. 17 Mar, 2020 11 commits
  4. 13 Mar, 2020 2 commits
    • Mark Rutland's avatar
      arm64: kvm: hyp: use cpus_have_final_cap() · b5475d8c
      Mark Rutland authored
      The KVM hyp code is only run after system capabilities have been
      finalized, and thus all const cap checks have been patched. This is
      noted in in __cpu_init_hyp_mode(), where we BUG() if called too early:
      
      | /*
      |  * Call initialization code, and switch to the full blown HYP code.
      |  * If the cpucaps haven't been finalized yet, something has gone very
      |  * wrong, and hyp will crash and burn when it uses any
      |  * cpus_have_const_cap() wrapper.
      |  */
      
      Given this, the hyp code can use cpus_have_final_cap() and avoid
      generating code to check the cpu_hwcaps array, which would be unsafe to
      run in hyp context.
      
      This patch migrate the KVM hyp code to cpus_have_final_cap(), avoiding
      this redundant code generation, and making it possible to detect if we
      accidentally invoke this code too early. In the latter case, the BUG()
      in cpus_have_final_cap() will cause a hyp panic.
      Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
      Reviewed-by: default avatarMarc Zyngier <maz@kernel.org>
      Cc: James Morse <james.morse@arm.com>
      Cc: Julien Thierry <julien.thierry.kdev@gmail.com>
      Cc: Suzuki Poulouse <suzuki.poulose@arm.com>
      Cc: Will Deacon <will@kernel.org>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      b5475d8c
    • Mark Rutland's avatar
      arm64: cpufeature: add cpus_have_final_cap() · 1db5cdec
      Mark Rutland authored
      When cpus_have_const_cap() was originally introduced it was intended to
      be safe in hyp context, where it is not safe to access the cpu_hwcaps
      array as cpus_have_cap() did. For more details see commit:
      
        a4023f68 ("arm64: Add hypervisor safe helper for checking constant capabilities")
      
      We then made use of cpus_have_const_cap() throughout the kernel.
      
      Subsequently, we had to defer updating the static_key associated with
      each capability in order to avoid lockdep complaints. To avoid breaking
      kernel-wide usage of cpus_have_const_cap(), this was updated to fall
      back to the cpu_hwcaps array if called before the static_keys were
      updated. As the kvm hyp code was only called later than this, the
      fallback is redundant but not functionally harmful. For more details,
      see commit:
      
        63a1e1c9 ("arm64/cpufeature: don't use mutex in bringup path")
      
      Today we have more users of cpus_have_const_cap() which are only called
      once the relevant static keys are initialized, and it would be
      beneficial to avoid the redundant code.
      
      To that end, this patch adds a new cpus_have_final_cap(), helper which
      is intend to be used in code which is only run once capabilities have
      been finalized, and will never check the cpus_hwcap array. This helps
      the compiler to generate better code as it no longer needs to generate
      code to address and test the cpus_hwcap array. To help catch misuse,
      cpus_have_final_cap() will BUG() if called before capabilities are
      finalized.
      
      In hyp context, BUG() will result in a hyp panic, but the specific BUG()
      instance will not be identified in the usual way.
      
      Comments are added to the various cpus_have_*_cap() helpers to describe
      the constraints on when they can be used. For clarity cpus_have_cap() is
      moved above the other helpers. Similarly the helpers are updated to use
      system_capabilities_finalized() consistently, and this is made
      __always_inline as required by its new callers.
      Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
      Reviewed-by: default avatarMarc Zyngier <maz@kernel.org>
      Reviewed-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
      Cc: Will Deacon <will@kernel.org>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      1db5cdec
  5. 11 Mar, 2020 1 commit
    • Mark Rutland's avatar
      arm64: entry: unmask IRQ in el0_sp() · f0c0d4b7
      Mark Rutland authored
      Currently, the EL0 SP alignment handler masks IRQs unnecessarily. It
      does so due to historic code sharing of the EL0 SP and PC alignment
      handlers, and branch predictor hardening applicable to the EL0 SP
      handler.
      
      We began masking IRQs in the EL0 SP alignment handler in commit:
      
        5dfc6ed2 ("arm64: entry: Apply BP hardening for high-priority synchronous exception")
      
      ... as this shared code with the EL0 PC alignment handler, and branch
      predictor hardening made it necessary to disable IRQs for early parts of
      the EL0 PC alignment handler. It was not necessary to mask IRQs during
      EL0 SP alignment exceptions, but it was not considered harmful to do so.
      
      This masking was carried forward into C code in commit:
      
        582f9583 ("arm64: entry: convert el0_sync to C")
      
      ... where the SP/PC cases were split into separate handlers, and the
      masking duplicated.
      
      Subsequently the EL0 PC alignment handler was refactored to perform
      branch predictor hardening before unmasking IRQs, in commit:
      
        bfe29874 ("arm64: entry-common: don't touch daif before bp-hardening")
      
      ... but the redundant masking of IRQs was not removed from the EL0 SP
      alignment handler.
      
      Let's do so now, and make it interruptible as with most other
      synchronous exception handlers.
      Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
      Cc: Will Deacon <will@kernel.org>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      Reviewed-by: default avatarJames Morse <james.morse@arm.com>
      f0c0d4b7
  6. 09 Mar, 2020 3 commits
  7. 06 Mar, 2020 7 commits
    • Ionela Voinescu's avatar
      clocksource/drivers/arm_arch_timer: validate arch_timer_rate · c265861a
      Ionela Voinescu authored
      Using an arch timer with a frequency of less than 1MHz can potentially
      result in incorrect functionality in systems that assume a reasonable
      rate of the arch timer of 1 to 50MHz, described as typical in the
      architecture specification.
      
      Therefore, warn if the arch timer rate is below 1MHz, which is
      considered atypical and worth emphasizing.
      Suggested-by: default avatarValentin Schneider <valentin.schneider@arm.com>
      Signed-off-by: default avatarIonela Voinescu <ionela.voinescu@arm.com>
      Acked-by: default avatarMarc Zyngier <maz@kernel.org>
      Cc: Marc Zyngier <maz@kernel.org>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      c265861a
    • Ionela Voinescu's avatar
      arm64: use activity monitors for frequency invariance · cd0ed03a
      Ionela Voinescu authored
      The Frequency Invariance Engine (FIE) is providing a frequency
      scaling correction factor that helps achieve more accurate
      load-tracking.
      
      So far, for arm and arm64 platforms, this scale factor has been
      obtained based on the ratio between the current frequency and the
      maximum supported frequency recorded by the cpufreq policy. The
      setting of this scale factor is triggered from cpufreq drivers by
      calling arch_set_freq_scale. The current frequency used in computation
      is the frequency requested by a governor, but it may not be the
      frequency that was implemented by the platform.
      
      This correction factor can also be obtained using a core counter and a
      constant counter to get information on the performance (frequency based
      only) obtained in a period of time. This will more accurately reflect
      the actual current frequency of the CPU, compared with the alternative
      implementation that reflects the request of a performance level from
      the OS.
      
      Therefore, implement arch_scale_freq_tick to use activity monitors, if
      present, for the computation of the frequency scale factor.
      
      The use of AMU counters depends on:
       - CONFIG_ARM64_AMU_EXTN - depents on the AMU extension being present
       - CONFIG_CPU_FREQ - the current frequency obtained using counter
         information is divided by the maximum frequency obtained from the
         cpufreq policy.
      
      While it is possible to have a combination of CPUs in the system with
      and without support for activity monitors, the use of counters for
      frequency invariance is only enabled for a CPU if all related CPUs
      (CPUs in the same frequency domain) support and have enabled the core
      and constant activity monitor counters. In this way, there is a clear
      separation between the policies for which arch_set_freq_scale (cpufreq
      based FIE) is used, and the policies for which arch_scale_freq_tick
      (counter based FIE) is used to set the frequency scale factor. For
      this purpose, a late_initcall_sync is registered to trigger validation
      work for policies that will enable or disable the use of AMU counters
      for frequency invariance. If CONFIG_CPU_FREQ is not defined, the use
      of counters is enabled on all CPUs only if all possible CPUs correctly
      support the necessary counters.
      Signed-off-by: default avatarIonela Voinescu <ionela.voinescu@arm.com>
      Reviewed-by: default avatarLukasz Luba <lukasz.luba@arm.com>
      Acked-by: default avatarSudeep Holla <sudeep.holla@arm.com>
      Cc: Sudeep Holla <sudeep.holla@arm.com>
      Cc: Will Deacon <will@kernel.org>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      cd0ed03a
    • Ionela Voinescu's avatar
      cpufreq: add function to get the hardware max frequency · bbce8eaa
      Ionela Voinescu authored
      Add weak function to return the hardware maximum frequency of a CPU,
      with the default implementation returning cpuinfo.max_freq, which is
      the best information we can generically get from the cpufreq framework.
      
      The default can be overwritten by a strong function in platforms
      that want to provide an alternative implementation, with more accurate
      information, obtained either from hardware or firmware.
      Signed-off-by: default avatarIonela Voinescu <ionela.voinescu@arm.com>
      Reviewed-by: default avatarValentin Schneider <valentin.schneider@arm.com>
      Acked-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
      Cc: Viresh Kumar <viresh.kumar@linaro.org>
      Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      bbce8eaa
    • Ionela Voinescu's avatar
      Documentation: arm64: document support for the AMU extension · 6abde908
      Ionela Voinescu authored
      The activity monitors extension is an optional extension introduced
      by the ARMv8.4 CPU architecture.
      
      Add initial documentation for the AMUv1 extension:
       - arm64/amu.txt: AMUv1 documentation
       - arm64/booting.txt: system registers initialisation
      Signed-off-by: default avatarIonela Voinescu <ionela.voinescu@arm.com>
      Reviewed-by: default avatarValentin Schneider <valentin.schneider@arm.com>
      Cc: Jonathan Corbet <corbet@lwn.net>
      Cc: Will Deacon <will@kernel.org>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      6abde908
    • Ionela Voinescu's avatar
      arm64/kvm: disable access to AMU registers from kvm guests · 4fcdf106
      Ionela Voinescu authored
      Access to the AMU counters should be disabled by default in kvm guests,
      as information from the counters might reveal activity in other guests
      or activity on the host.
      
      Therefore, disable access to AMU registers from EL0 and EL1 in kvm
      guests by:
       - Hiding the presence of the extension in the feature register
         (SYS_ID_AA64PFR0_EL1) on the VCPU.
       - Disabling access to the AMU registers before switching to the guest.
       - Trapping accesses and injecting an undefined instruction into the
         guest.
      Signed-off-by: default avatarIonela Voinescu <ionela.voinescu@arm.com>
      Reviewed-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
      Reviewed-by: default avatarValentin Schneider <valentin.schneider@arm.com>
      Acked-by: default avatarMarc Zyngier <maz@kernel.org>
      Cc: Will Deacon <will@kernel.org>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
      Cc: Julien Thierry <julien.thierry.kdev@gmail.com>
      Cc: James Morse <james.morse@arm.com>
      Cc: Marc Zyngier <maz@kernel.org>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      4fcdf106
    • Ionela Voinescu's avatar
      arm64: trap to EL1 accesses to AMU counters from EL0 · 87a1f063
      Ionela Voinescu authored
      The activity monitors extension is an optional extension introduced
      by the ARMv8.4 CPU architecture. In order to access the activity
      monitors counters safely, if desired, the kernel should detect the
      presence of the extension through the feature register, and mediate
      the access.
      
      Therefore, disable direct accesses to activity monitors counters
      from EL0 (userspace) and trap them to EL1 (kernel).
      
      To be noted that the ARM64_AMU_EXTN kernel config does not have an
      effect on this code. Given that the amuserenr_el0 resets to an
      UNKNOWN value, setting the trap of EL0 accesses to EL1 is always
      attempted for safety and security considerations. Therefore firmware
      should still ensure accesses to AMU registers are not trapped in
      EL2/EL3 as this code cannot be bypassed if the CPU implements the
      Activity Monitors Unit.
      Signed-off-by: default avatarIonela Voinescu <ionela.voinescu@arm.com>
      Reviewed-by: default avatarJames Morse <james.morse@arm.com>
      Reviewed-by: default avatarValentin Schneider <valentin.schneider@arm.com>
      Reviewed-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
      Cc: Steve Capper <steve.capper@arm.com>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Will Deacon <will@kernel.org>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      87a1f063
    • Ionela Voinescu's avatar
      arm64: add support for the AMU extension v1 · 2c9d45b4
      Ionela Voinescu authored
      The activity monitors extension is an optional extension introduced
      by the ARMv8.4 CPU architecture. This implements basic support for
      version 1 of the activity monitors architecture, AMUv1.
      
      This support includes:
      - Extension detection on each CPU (boot, secondary, hotplugged)
      - Register interface for AMU aarch64 registers
      Signed-off-by: default avatarIonela Voinescu <ionela.voinescu@arm.com>
      Reviewed-by: default avatarValentin Schneider <valentin.schneider@arm.com>
      Cc: Mark Rutland <mark.rutland@arm.com>
      Cc: Marc Zyngier <maz@kernel.org>
      Cc: Suzuki K Poulose <suzuki.poulose@arm.com>
      Cc: Will Deacon <will@kernel.org>
      Cc: Catalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      2c9d45b4
  8. 04 Mar, 2020 3 commits
    • Remi Denis-Courmont's avatar
      arm64: remove gratuitious/stray .ltorg stanzas · 857a141d
      Remi Denis-Courmont authored
      There are no applicable literals above them.
      Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
      Signed-off-by: default avatarRemi Denis-Courmont <remi.denis.courmont@huawei.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      857a141d
    • Anshuman Khandual's avatar
      arm64/mm: Enable memory hot remove · bbd6ec60
      Anshuman Khandual authored
      The arch code for hot-remove must tear down portions of the linear map and
      vmemmap corresponding to memory being removed. In both cases the page
      tables mapping these regions must be freed, and when sparse vmemmap is in
      use the memory backing the vmemmap must also be freed.
      
      This patch adds unmap_hotplug_range() and free_empty_tables() helpers which
      can be used to tear down either region and calls it from vmemmap_free() and
      ___remove_pgd_mapping(). The free_mapped argument determines whether the
      backing memory will be freed.
      
      It makes two distinct passes over the kernel page table. In the first pass
      with unmap_hotplug_range() it unmaps, invalidates applicable TLB cache and
      frees backing memory if required (vmemmap) for each mapped leaf entry. In
      the second pass with free_empty_tables() it looks for empty page table
      sections whose page table page can be unmapped, TLB invalidated and freed.
      
      While freeing intermediate level page table pages bail out if any of its
      entries are still valid. This can happen for partially filled kernel page
      table either from a previously attempted failed memory hot add or while
      removing an address range which does not span the entire page table page
      range.
      
      The vmemmap region may share levels of table with the vmalloc region.
      There can be conflicts between hot remove freeing page table pages with
      a concurrent vmalloc() walking the kernel page table. This conflict can
      not just be solved by taking the init_mm ptl because of existing locking
      scheme in vmalloc(). So free_empty_tables() implements a floor and ceiling
      method which is borrowed from user page table tear with free_pgd_range()
      which skips freeing page table pages if intermediate address range is not
      aligned or maximum floor-ceiling might not own the entire page table page.
      
      Boot memory on arm64 cannot be removed. Hence this registers a new memory
      hotplug notifier which prevents boot memory offlining and it's removal.
      
      While here update arch_add_memory() to handle __add_pages() failures by
      just unmapping recently added kernel linear mapping. Now enable memory hot
      remove on arm64 platforms by default with ARCH_ENABLE_MEMORY_HOTREMOVE.
      
      This implementation is overall inspired from kernel page table tear down
      procedure on X86 architecture and user page table tear down method.
      
      [Mike and Catalin added P4D page table level support]
      Reviewed-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: default avatarMike Rapoport <rppt@linux.ibm.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      Signed-off-by: default avatarAnshuman Khandual <anshuman.khandual@arm.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      bbd6ec60
    • Anshuman Khandual's avatar
      arm64/mm: Hold memory hotplug lock while walking for kernel page table dump · bf2b59f6
      Anshuman Khandual authored
      The arm64 page table dump code can race with concurrent modification of the
      kernel page tables. When a leaf entries are modified concurrently, the dump
      code may log stale or inconsistent information for a VA range, but this is
      otherwise not harmful.
      
      When intermediate levels of table are freed, the dump code will continue to
      use memory which has been freed and potentially reallocated for another
      purpose. In such cases, the dump code may dereference bogus addresses,
      leading to a number of potential problems.
      
      Intermediate levels of table may by freed during memory hot-remove,
      which will be enabled by a subsequent patch. To avoid racing with
      this, take the memory hotplug lock when walking the kernel page table.
      Acked-by: default avatarDavid Hildenbrand <david@redhat.com>
      Acked-by: default avatarMark Rutland <mark.rutland@arm.com>
      Acked-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      Reviewed-by: default avatarSteven Price <steven.price@arm.com>
      Signed-off-by: default avatarAnshuman Khandual <anshuman.khandual@arm.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      bf2b59f6
  9. 02 Mar, 2020 3 commits
  10. 28 Feb, 2020 1 commit
  11. 27 Feb, 2020 5 commits
    • Liguang Zhang's avatar
      firmware: arm_sdei: clean up sdei_event_create() · f7d5ef0c
      Liguang Zhang authored
      Function sdei_event_find() is always called in sdei_event_create(), but
      it is already called in sdei_event_register(). This code is trying to
      avoid a double-create of the same event, which can't happen as we still
      hold the sdei_events_lock. We can remove this needless sdei_event_find()
      call.
      Signed-off-by: default avatarLiguang Zhang <zhangliguang@linux.alibaba.com>
      [expanded commit message]
      Signed-off-by: default avatarJames Morse <james.morse@arm.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      f7d5ef0c
    • James Morse's avatar
      firmware: arm_sdei: Use cpus_read_lock() to avoid races with cpuhp · 54f529a6
      James Morse authored
      SDEI has private events that need registering and enabling on each CPU.
      CPUs can come and go while we are trying to do this. SDEI tries to avoid
      these problems by setting the reregister flag before the register call,
      so any CPUs that come online register the event too. Sticking plaster
      like this doesn't work, as if the register call fails, a CPU that
      subsequently comes online will register the event before reregister
      is cleared.
      
      Take cpus_read_lock() around the register and enable calls. We don't
      want surprise CPUs to do the wrong thing if they race with these calls
      failing.
      Signed-off-by: default avatarJames Morse <james.morse@arm.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      54f529a6
    • Liguang Zhang's avatar
      firmware: arm_sdei: fix possible double-lock on hibernate error path · c66d52b1
      Liguang Zhang authored
      We call sdei_reregister_event() with sdei_list_lock held, if the register
      fails we call sdei_event_destroy() which also acquires sdei_list_lock
      thus creating A-A deadlock.
      
      Add '_llocked' to sdei_reregister_event(), to indicate the list lock
      is held, and add a _llocked variant of sdei_event_destroy().
      
      Fixes: da351827 ("firmware: arm_sdei: Add support for CPU and system power states")
      Signed-off-by: default avatarLiguang Zhang <zhangliguang@linux.alibaba.com>
      [expanded subject, added wrappers instead of duplicating contents]
      Signed-off-by: default avatarJames Morse <james.morse@arm.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      c66d52b1
    • James Morse's avatar
      firmware: arm_sdei: fix double-lock on hibernate with shared events · 6ded0b61
      James Morse authored
      SDEI has private events that must be registered on each CPU. When
      CPUs come and go they must re-register and re-enable their private
      events. Each event has flags to indicate whether this should happen
      to protect against an event being registered on a CPU coming online,
      while all the others are unregistering the event.
      
      These flags are protected by the sdei_list_lock spinlock, because
      the cpuhp callbacks can't take the mutex.
      
      Hibernate needs to unregister all events, but keep the in-memory
      re-register and re-enable as they are. sdei_unregister_shared()
      takes the spinlock to walk the list, then calls _sdei_event_unregister()
      on each shared event. _sdei_event_unregister() tries to take the
      same spinlock to update re-register and re-enable. This doesn't go
      so well.
      
      Push the re-register and re-enable updates out to their callers.
      sdei_unregister_shared() doesn't want these values updated, so
      doesn't need to do anything.
      
      This also fixes shared events getting lost over hibernate as this
      path made them look unregistered.
      
      Fixes: da351827 ("firmware: arm_sdei: Add support for CPU and system power states")
      Reported-by: default avatarLiguang Zhang <zhangliguang@linux.alibaba.com>
      Signed-off-by: default avatarJames Morse <james.morse@arm.com>
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      6ded0b61
    • Mark Rutland's avatar
      arm64: mm: convert cpu_do_switch_mm() to C · 25b92693
      Mark Rutland authored
      There's no reason that cpu_do_switch_mm() needs to be written as an
      assembly function, and having it as a C function would make it easier to
      maintain.
      
      This patch converts cpu_do_switch_mm() to C, removing code that this
      change makes redundant (e.g. the mmid macro). Since the header comment
      was stale and the prototype now implies all the necessary information,
      this comment is removed. The 'pgd_phys' argument is made a phys_addr_t
      to match the return type of virt_to_phys().
      
      At the same time, post_ttbr_update_workaround() is updated to use
      IS_ENABLED(), which allows the compiler to figure out it can elide calls
      for !CONFIG_CAVIUM_ERRATUM_27456 builds.
      
      There should be no functional change as a result of this patch.
      Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
      Cc: Will Deacon <will@kernel.org>
      [catalin.marinas@arm.com: change comments from asm-style to C-style]
      Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
      25b92693