1. 25 8月, 2022 1 次提交
  2. 27 7月, 2022 1 次提交
    • R
      ACPI: CPPC: Do not prevent CPPC from working in the future · 4f4179fc
      Rafael J. Wysocki 提交于
      There is a problem with the current revision checks in
      is_cppc_supported() that they essentially prevent the CPPC support
      from working if a new _CPC package format revision being a proper
      superset of the v3 and only causing _CPC to return a package with more
      entries (while retaining the types and meaning of the entries defined by
      the v3) is introduced in the future and used by the platform firmware.
      
      In that case, as long as the number of entries in the _CPC return
      package is at least CPPC_V3_NUM_ENT, it should be perfectly fine to
      use the v3 support code and disregard the additional package entries
      added by the new package format revision.
      
      For this reason, drop is_cppc_supported() altogether, put the revision
      checks directly into acpi_cppc_processor_probe() so they are easier to
      follow and rework them to take the case mentioned above into account.
      
      Fixes: 4773e77c ("ACPI / CPPC: Add support for CPPC v3")
      Cc: 4.18+ <stable@vger.kernel.org> # 4.18+
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      4f4179fc
  3. 19 7月, 2022 1 次提交
  4. 06 7月, 2022 2 次提交
  5. 25 5月, 2022 1 次提交
  6. 20 5月, 2022 3 次提交
    • P
      cpufreq: CPPC: Enable fast_switch · 3cc30dd0
      Pierre Gondois 提交于
      The communication mean of the _CPC desired performance can be
      PCC, System Memory, System IO, or Functional Fixed Hardware.
      
      commit b7898fda ("cpufreq: Support for fast frequency switching")
      fast_switching is 'for switching CPU frequencies from interrupt
      context'.
      Writes to SystemMemory and SystemIo are fast and suitable this.
      This is not the case for PCC and might not be the case for FFH.
      
      Enable fast_switching for the cppc_cpufreq driver in above cases.
      
      Add cppc_allow_fast_switch() to check the desired performance
      register address space and set fast_switching accordingly.
      Signed-off-by: NPierre Gondois <pierre.gondois@arm.com>
      Reviewed-by: NSudeep Holla <sudeep.holla@arm.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      3cc30dd0
    • P
      ACPI: CPPC: Assume no transition latency if no PCCT · 6380b7b2
      Pierre Gondois 提交于
      The transition_delay_us (struct cpufreq_policy) is currently defined
      as:
        Preferred average time interval between consecutive invocations of
        the driver to set the frequency for this policy.  To be set by the
        scaling driver (0, which is the default, means no preference).
      The transition_latency represents the amount of time necessary for a
      CPU to change its frequency.
      
      A PCCT table advertises mutliple values:
      - pcc_nominal: Expected latency to process a command, in microseconds
      - pcc_mpar: The maximum number of periodic requests that the subspace
        channel can support, reported in commands per minute. 0 indicates no
        limitation.
      - pcc_mrtt: The minimum amount of time that OSPM must wait after the
        completion of a command before issuing the next command,
        in microseconds.
      cppc_get_transition_latency() allows to get the max of them.
      
      commit d4f3388a ("cpufreq / CPPC: Set platform specific
      transition_delay_us") allows to select transition_delay_us based on
      the platform, and fallbacks to cppc_get_transition_latency()
      otherwise.
      
      If _CPC objects are not using PCC channels (no PPCT table), the
      transition_delay_us is set to CPUFREQ_ETERNAL, leading to really long
      periods between frequency updates (~4s).
      
      If the desired_reg, where performance requests are written, is in
      SystemMemory or SystemIo ACPI address space, there is no delay
      in requests. So return 0 instead of CPUFREQ_ETERNAL, leading to
      transition_delay_us being set to LATENCY_MULTIPLIER us (1000 us).
      
      This patch also adds two macros to check the address spaces.
      Signed-off-by: NPierre Gondois <pierre.gondois@arm.com>
      Reviewed-by: NSudeep Holla <sudeep.holla@arm.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      6380b7b2
    • P
      ACPI: CPPC: Check _OSC for flexible address space · 0651ab90
      Pierre Gondois 提交于
      ACPI 6.2 Section 6.2.11.2 'Platform-Wide OSPM Capabilities':
        Starting with ACPI Specification 6.2, all _CPC registers can be in
        PCC, System Memory, System IO, or Functional Fixed Hardware address
        spaces. OSPM support for this more flexible register space scheme is
        indicated by the “Flexible Address Space for CPPC Registers” _OSC bit
      
      Otherwise (cf ACPI 6.1, s8.4.7.1.1.X), _CPC registers must be in:
      - PCC or Functional Fixed Hardware address space if defined
      - SystemMemory address space (NULL register) if not defined
      
      Add the corresponding _OSC bit and check it when parsing _CPC objects.
      Signed-off-by: NPierre Gondois <pierre.gondois@arm.com>
      Reviewed-by: NSudeep Holla <sudeep.holla@arm.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      0651ab90
  7. 26 3月, 2022 2 次提交
  8. 17 3月, 2022 1 次提交
  9. 11 3月, 2022 1 次提交
  10. 18 1月, 2022 2 次提交
  11. 31 12月, 2021 3 次提交
  12. 29 12月, 2021 1 次提交
  13. 23 12月, 2021 1 次提交
  14. 24 11月, 2021 1 次提交
  15. 30 10月, 2021 1 次提交
  16. 08 9月, 2021 1 次提交
    • R
      ACPI: CPPC: Introduce cppc_get_nominal_perf() · 0654cf05
      Rafael J. Wysocki 提交于
      On some systems the nominal_perf value retrieved via CPPC is just
      a constant and fetching it doesn't require accessing any registers,
      so if it is the only CPPC capability that's needed, it is wasteful
      to run cppc_get_perf_caps() in order to get just that value alone,
      especially when this is done for CPUs other than the one running
      the code.
      
      For this reason, introduce cppc_get_nominal_perf() allowing
      nominal_perf to be obtained individually, by generalizing the
      existing cppc_get_desired_perf() (and renaming it) so it can be
      used to retrieve any specific CPPC capability value.
      
      While at it, clean up the cppc_get_desired_perf() kerneldoc comment
      a bit.
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      0654cf05
  17. 09 4月, 2021 1 次提交
    • N
      ACPI: CPPC: Replace cppc_attr with kobj_attribute · 2bc6262c
      Nathan Chancellor 提交于
      All of the CPPC sysfs show functions are called via indirect call in
      kobj_attr_show(), where they should be of type
      
      ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, char *buf);
      
      because that is the type of the ->show() member in
      'struct kobj_attribute' but they are actually of type
      
      ssize_t (*show)(struct kobject *kobj, struct attribute *attr, char *buf);
      
      because of the ->show() member in 'struct cppc_attr', resulting in a
      Control Flow Integrity violation [1].
      
      $ cat /sys/devices/system/cpu/cpu0/acpi_cppc/highest_perf
      3400
      
      $ dmesg | grep "CFI failure"
      [  175.970559] CFI failure (target: show_highest_perf+0x0/0x8):
      
      As far as I can tell, the only difference between 'struct cppc_attr'
      and 'struct kobj_attribute' aside from the type of the attr parameter
      is the type of the count parameter in the ->store() member (ssize_t vs.
      size_t), which does not actually matter because all of these nodes are
      read-only.
      
      Eliminate 'struct cppc_attr' in favor of 'struct kobj_attribute' to fix
      the violation.
      
      [1]: https://lore.kernel.org/r/20210401233216.2540591-1-samitolvanen@google.com/
      
      Fixes: 158c998e ("ACPI / CPPC: add sysfs support to compute delivered performance")
      Link: https://github.com/ClangBuiltLinux/linux/issues/1343Signed-off-by: NNathan Chancellor <nathan@kernel.org>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      2bc6262c
  18. 08 4月, 2021 1 次提交
  19. 24 3月, 2021 1 次提交
  20. 20 3月, 2021 1 次提交
  21. 22 1月, 2021 2 次提交
    • I
      ACPI: CPPC: initialise vaddr pointers to NULL · 26692cd9
      Ionela Voinescu 提交于
      Properly initialise vaddr pointers in cpc_read() and cpc_write() to
      NULL instead of 0.
      
      This fixes the following sparse warnings:
      
      drivers/acpi/cppc_acpi.c:937:31: warning: Using plain integer as NULL pointer
      drivers/acpi/cppc_acpi.c:982:31: warning: Using plain integer as NULL pointer
      Signed-off-by: NIonela Voinescu <ionela.voinescu@arm.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      26692cd9
    • I
      ACPI: CPPC: add __iomem annotation to generic_comm_base pointer · 1d9b4abe
      Ionela Voinescu 提交于
      ppc_comm_addr is a virtual address to the PCC space and it's annotated
      with __iomem. Therefore, generic_comm_base which gets assigned the value of
      pcc_comm_address should be annotated as well.
      
      This already happens in check_pcc_chan(), but not in send_pcc_cmd(), which
      results in the following sparse warnings:
      
      drivers/acpi/cppc_acpi.c:237:18: warning: cast removes address space '__iomem' of expression
      drivers/acpi/cppc_acpi.c:299:9: warning: incorrect type in argument 2 (different address spaces)
      drivers/acpi/cppc_acpi.c:299:9:    expected void volatile [noderef] __iomem *addr
      drivers/acpi/cppc_acpi.c:299:9:    got unsigned short *
      drivers/acpi/cppc_acpi.c:302:9: warning: incorrect type in argument 2 (different address spaces)
      drivers/acpi/cppc_acpi.c:302:9:    expected void volatile [noderef] __iomem *addr
      drivers/acpi/cppc_acpi.c:302:9:    got unsigned short *
      Signed-off-by: NIonela Voinescu <ionela.voinescu@arm.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      1d9b4abe
  22. 16 12月, 2020 2 次提交
    • I
      cppc_cpufreq: replace per-cpu data array with a list · a28b2bfc
      Ionela Voinescu 提交于
      The cppc_cpudata per-cpu storage was inefficient (1) additional to causing
      functional issues (2) when CPUs are hotplugged out, due to per-cpu data
      being improperly initialised.
      
      (1) The amount of information needed for CPPC performance control in its
          cpufreq driver depends on the domain (PSD) coordination type:
      
          ANY:    One set of CPPC control and capability data (e.g desired
                  performance, highest/lowest performance, etc) applies to all
                  CPUs in the domain.
      
          ALL:    Same as ANY. To be noted that this type is not currently
                  supported. When supported, information about which CPUs
                  belong to a domain is needed in order for frequency change
                  requests to be sent to each of them.
      
          HW:     It's necessary to store CPPC control and capability
                  information for all the CPUs. HW will then coordinate the
                  performance state based on their limitations and requests.
      
          NONE:   Same as HW. No HW coordination is expected.
      
          Despite this, the previous initialisation code would indiscriminately
          allocate memory for all CPUs (all_cpu_data) and unnecessarily
          duplicate performance capabilities and the domain sharing mask and type
          for each possible CPU.
      
      (2) With the current per-cpu structure, when having ANY coordination,
          the cppc_cpudata cpu information is not initialised (will remain 0)
          for all CPUs in a policy, other than policy->cpu. When policy->cpu is
          hotplugged out, the driver will incorrectly use the uninitialised (0)
          value of the other CPUs when making frequency changes. Additionally,
          the previous values stored in the perf_ctrls.desired_perf will be
          lost when policy->cpu changes.
      
      Therefore replace the array of per cpu data with a list. The memory for
      each structure is allocated at policy init, where a single structure
      can be allocated per policy, not per cpu. In order to accommodate the
      struct list_head node in the cppc_cpudata structure, the now unused cpu
      and cur_policy variables are removed.
      
      For example, on a arm64 Juno platform with 6 CPUs: (0, 1, 2, 3) in PSD1,
      (4, 5) in PSD2 - ANY coordination, the memory allocation comparison shows:
      
      Before patch:
      
       - ANY coordination:
         total    slack      req alloc/free  caller
             0        0        0     0/1     _kernel_size_le_hi32+0x0xffff800008ff7810
             0        0        0     0/6     _kernel_size_le_hi32+0x0xffff800008ff7808
           128       80       48     1/0     _kernel_size_le_hi32+0x0xffff800008ffc070
           768        0      768     6/0     _kernel_size_le_hi32+0x0xffff800008ffc0e4
      
      After patch:
      
       - ANY coordination:
          total    slack      req alloc/free  caller
           256        0      256     2/0     _kernel_size_le_hi32+0x0xffff800008fed410
             0        0        0     0/2     _kernel_size_le_hi32+0x0xffff800008fed274
      
      Additional notes:
       - A pointer to the policy's cppc_cpudata is stored in policy->driver_data
       - Driver registration is skipped if _CPC entries are not present.
      Signed-off-by: NIonela Voinescu <ionela.voinescu@arm.com>
      Tested-by: NMian Yousaf Kaukab <ykaukab@suse.de>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      a28b2bfc
    • I
      ACPI: processor: fix NONE coordination for domain mapping failure · bca3e43c
      Ionela Voinescu 提交于
      For errors parsing the _PSD domains, a separate domain is returned for
      each CPU in the failed _PSD domain with no coordination (as per previous
      comment). But contrary to the intention, the code was setting
      CPUFREQ_SHARED_TYPE_ALL as coordination type.
      
      Change shared_type to CPUFREQ_SHARED_TYPE_NONE in case of errors parsing
      the domain information. The function still returns the error and the caller
      is free to bail out the domain initialisation altogether in that case.
      
      Given that both functions return domains with a single CPU, this change
      does not affect the functionality, but clarifies the intention.
      Signed-off-by: NIonela Voinescu <ionela.voinescu@arm.com>
      Acked-by: NViresh Kumar <viresh.kumar@linaro.org>
      [ rjw: Subject edit ]
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      bca3e43c
  23. 11 12月, 2020 1 次提交
  24. 28 5月, 2020 1 次提交
  25. 27 4月, 2020 1 次提交
  26. 28 3月, 2020 1 次提交
  27. 18 10月, 2019 1 次提交
    • J
      ACPI: CPPC: Set pcc_data[pcc_ss_id] to NULL in acpi_cppc_processor_exit() · 56a0b978
      John Garry 提交于
      When enabling KASAN and DEBUG_TEST_DRIVER_REMOVE, I find this KASAN
      warning:
      
      [   20.872057] BUG: KASAN: use-after-free in pcc_data_alloc+0x40/0xb8
      [   20.878226] Read of size 4 at addr ffff00236cdeb684 by task swapper/0/1
      [   20.884826]
      [   20.886309] CPU: 19 PID: 1 Comm: swapper/0 Not tainted 5.4.0-rc1-00009-ge7f7df3db5bf-dirty #289
      [   20.894994] Hardware name: Huawei D06 /D06, BIOS Hisilicon D06 UEFI RC0 - V1.16.01 03/15/2019
      [   20.903505] Call trace:
      [   20.905942]  dump_backtrace+0x0/0x200
      [   20.909593]  show_stack+0x14/0x20
      [   20.912899]  dump_stack+0xd4/0x130
      [   20.916291]  print_address_description.isra.9+0x6c/0x3b8
      [   20.921592]  __kasan_report+0x12c/0x23c
      [   20.925417]  kasan_report+0xc/0x18
      [   20.928808]  __asan_load4+0x94/0xb8
      [   20.932286]  pcc_data_alloc+0x40/0xb8
      [   20.935938]  acpi_cppc_processor_probe+0x4e8/0xb08
      [   20.940717]  __acpi_processor_start+0x48/0xb0
      [   20.945062]  acpi_processor_start+0x40/0x60
      [   20.949235]  really_probe+0x118/0x548
      [   20.952887]  driver_probe_device+0x7c/0x148
      [   20.957059]  device_driver_attach+0x94/0xa0
      [   20.961231]  __driver_attach+0xa4/0x110
      [   20.965055]  bus_for_each_dev+0xe8/0x158
      [   20.968966]  driver_attach+0x30/0x40
      [   20.972531]  bus_add_driver+0x234/0x2f0
      [   20.976356]  driver_register+0xbc/0x1d0
      [   20.980182]  acpi_processor_driver_init+0x40/0xe4
      [   20.984875]  do_one_initcall+0xb4/0x254
      [   20.988700]  kernel_init_freeable+0x24c/0x2f8
      [   20.993047]  kernel_init+0x10/0x118
      [   20.996524]  ret_from_fork+0x10/0x18
      [   21.000087]
      [   21.001567] Allocated by task 1:
      [   21.004785]  save_stack+0x28/0xc8
      [   21.008089]  __kasan_kmalloc.isra.9+0xbc/0xd8
      [   21.012435]  kasan_kmalloc+0xc/0x18
      [   21.015913]  pcc_data_alloc+0x94/0xb8
      [   21.019564]  acpi_cppc_processor_probe+0x4e8/0xb08
      [   21.024343]  __acpi_processor_start+0x48/0xb0
      [   21.028689]  acpi_processor_start+0x40/0x60
      [   21.032860]  really_probe+0x118/0x548
      [   21.036512]  driver_probe_device+0x7c/0x148
      [   21.040684]  device_driver_attach+0x94/0xa0
      [   21.044855]  __driver_attach+0xa4/0x110
      [   21.048680]  bus_for_each_dev+0xe8/0x158
      [   21.052591]  driver_attach+0x30/0x40
      [   21.056155]  bus_add_driver+0x234/0x2f0
      [   21.059980]  driver_register+0xbc/0x1d0
      [   21.063805]  acpi_processor_driver_init+0x40/0xe4
      [   21.068497]  do_one_initcall+0xb4/0x254
      [   21.072322]  kernel_init_freeable+0x24c/0x2f8
      [   21.076667]  kernel_init+0x10/0x118
      [   21.080144]  ret_from_fork+0x10/0x18
      [   21.083707]
      [   21.085186] Freed by task 1:
      [   21.088056]  save_stack+0x28/0xc8
      [   21.091360]  __kasan_slab_free+0x118/0x180
      [   21.095445]  kasan_slab_free+0x10/0x18
      [   21.099183]  kfree+0x80/0x268
      [   21.102139]  acpi_cppc_processor_exit+0x1a8/0x1b8
      [   21.106832]  acpi_processor_stop+0x70/0x80
      [   21.110917]  really_probe+0x174/0x548
      [   21.114568]  driver_probe_device+0x7c/0x148
      [   21.118740]  device_driver_attach+0x94/0xa0
      [   21.122912]  __driver_attach+0xa4/0x110
      [   21.126736]  bus_for_each_dev+0xe8/0x158
      [   21.130648]  driver_attach+0x30/0x40
      [   21.134212]  bus_add_driver+0x234/0x2f0
      [   21.0x10/0x18
      [   21.161764]
      [   21.163244] The buggy address belongs to the object at ffff00236cdeb600
      [   21.163244]  which belongs to the cache kmalloc-256 of size 256
      [   21.175750] The buggy address is located 132 bytes inside of
      [   21.175750]  256-byte region [ffff00236cdeb600, ffff00236cdeb700)
      [   21.187473] The buggy address belongs to the page:
      [   21.192254] page:fffffe008d937a00 refcount:1 mapcount:0 mapping:ffff002370c0fa00 index:0x0 compound_mapcount: 0
      [   21.202331] flags: 0x1ffff00000010200(slab|head)
      [   21.206940] raw: 1ffff00000010200 dead000000000100 dead000000000122 ffff002370c0fa00
      [   21.214671] raw: 0000000000000000 00000000802a002a 00000001ffffffff 0000000000000000
      [   21.222400] page dumped because: kasan: bad access detected
      [   21.227959]
      [   21.229438] Memory state around the buggy address:
      [   21.234218]  ffff00236cdeb580: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
      [   21.241427]  ffff00236cdeb600: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      [   21.248637] >ffff00236cdeb680: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      [   21.255845]                    ^
      [   21.259062]  ffff00236cdeb700: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
      [   21.266272]  ffff00236cdeb780: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      [   21.273480] ==================================================================
      
      It seems that global pcc_data[pcc_ss_id] can be freed in
      acpi_cppc_processor_exit(), but we may later reference this value, so
      NULLify it when freed.
      
      Also remove the useless setting of data "pcc_channel_acquired", which
      we're about to free.
      
      Fixes: 85b1407b ("ACPI / CPPC: Make CPPC ACPI driver aware of PCC subspace IDs")
      Signed-off-by: NJohn Garry <john.garry@huawei.com>
      Cc: 4.15+ <stable@vger.kernel.org> # 4.15+
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      56a0b978
  28. 28 8月, 2019 1 次提交
    • A
      ACPI / CPPC: do not require the _PSD method · 4c4cdc4c
      Al Stone 提交于
      According to the ACPI 6.3 specification, the _PSD method is optional
      when using CPPC.  The underlying assumption is that each CPU can change
      frequency independently from all other CPUs; _PSD is provided to tell
      the OS that some processors can NOT do that.
      
      However, the acpi_get_psd() function returns ENODEV if there is no _PSD
      method present, or an ACPI error status if an error occurs when evaluating
      _PSD, if present.  This makes _PSD mandatory when using CPPC, in violation
      of the specification, and only on Linux.
      
      This has forced some firmware writers to provide a dummy _PSD, even though
      it is irrelevant, but only because Linux requires it; other OSPMs follow
      the spec.  We really do not want to have OS specific ACPI tables, though.
      
      So, correct acpi_get_psd() so that it does not return an error if there
      is no _PSD method present, but does return a failure when the method can
      not be executed properly.  This allows _PSD to be optional as it should
      be.
      Signed-off-by: NAl Stone <ahs3@redhat.com>
      Signed-off-by: NRafael J. Wysocki <rafael.j.wysocki@intel.com>
      4c4cdc4c
  29. 05 6月, 2019 1 次提交
  30. 27 3月, 2019 1 次提交
  31. 26 3月, 2019 1 次提交