]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
Merge tag 'v6.18-p1' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 4 Oct 2025 21:59:29 +0000 (14:59 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 4 Oct 2025 21:59:29 +0000 (14:59 -0700)
Pull crypto updates from Herbert Xu:
 "Drivers:
   - Add ciphertext hiding support to ccp
   - Add hashjoin, gather and UDMA data move features to hisilicon
   - Add lz4 and lz77_only to hisilicon
   - Add xilinx hwrng driver
   - Add ti driver with ecb/cbc aes support
   - Add ring buffer idle and command queue telemetry for GEN6 in qat

  Others:
   - Use rcu_dereference_all to stop false alarms in rhashtable
   - Fix CPU number wraparound in padata"

* tag 'v6.18-p1' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (78 commits)
  dt-bindings: rng: hisi-rng: convert to DT schema
  crypto: doc - Add explicit title heading to API docs
  hwrng: ks-sa - fix division by zero in ks_sa_rng_init
  KEYS: X.509: Fix Basic Constraints CA flag parsing
  crypto: anubis - simplify return statement in anubis_mod_init
  crypto: hisilicon/qm - set NULL to qm->debug.qm_diff_regs
  crypto: hisilicon/qm - clear all VF configurations in the hardware
  crypto: hisilicon - enable error reporting again
  crypto: hisilicon/qm - mask axi error before memory init
  crypto: hisilicon/qm - invalidate queues in use
  crypto: qat - Return pointer directly in adf_ctl_alloc_resources
  crypto: aspeed - Fix dma_unmap_sg() direction
  rhashtable: Use rcu_dereference_all and rcu_dereference_all_check
  crypto: comp - Use same definition of context alloc and free ops
  crypto: omap - convert from tasklet to BH workqueue
  crypto: qat - Replace kzalloc() + copy_from_user() with memdup_user()
  crypto: caam - double the entropy delay interval for retry
  padata: WQ_PERCPU added to alloc_workqueue users
  padata: replace use of system_unbound_wq with system_dfl_wq
  crypto: cryptd - WQ_PERCPU added to alloc_workqueue users
  ...

1  2 
MAINTAINERS
drivers/char/hw_random/Kconfig
drivers/crypto/Kconfig
drivers/crypto/Makefile
drivers/crypto/ccp/sev-dev.c
drivers/crypto/ccp/sev-dev.h
include/linux/rcupdate.h

diff --cc MAINTAINERS
Simple merge
Simple merge
Simple merge
Simple merge
index 8dff5c2c40fdf1661302274eb235d7371bf79350,6c116f6f9b792b9e0d327f009863bcbb10dda087..0d13d47c164bb766a3093353cfe607f74177d103
@@@ -1089,165 -1076,88 +1092,247 @@@ static void snp_set_hsave_pa(void *arg
        wrmsrq(MSR_VM_HSAVE_PA, 0);
  }
  
 +/* Hypervisor Fixed pages API interface */
 +static void snp_hv_fixed_pages_state_update(struct sev_device *sev,
 +                                          enum snp_hv_fixed_pages_state page_state)
 +{
 +      struct snp_hv_fixed_pages_entry *entry;
 +
 +      /* List is protected by sev_cmd_mutex */
 +      lockdep_assert_held(&sev_cmd_mutex);
 +
 +      if (list_empty(&snp_hv_fixed_pages))
 +              return;
 +
 +      list_for_each_entry(entry, &snp_hv_fixed_pages, list)
 +              entry->page_state = page_state;
 +}
 +
 +/*
 + * Allocate HV_FIXED pages in 2MB aligned sizes to ensure the whole
 + * 2MB pages are marked as HV_FIXED.
 + */
 +struct page *snp_alloc_hv_fixed_pages(unsigned int num_2mb_pages)
 +{
 +      struct psp_device *psp_master = psp_get_master_device();
 +      struct snp_hv_fixed_pages_entry *entry;
 +      struct sev_device *sev;
 +      unsigned int order;
 +      struct page *page;
 +
 +      if (!psp_master || !psp_master->sev_data)
 +              return NULL;
 +
 +      sev = psp_master->sev_data;
 +
 +      order = get_order(PMD_SIZE * num_2mb_pages);
 +
 +      /*
 +       * SNP_INIT_EX is protected by sev_cmd_mutex, therefore this list
 +       * also needs to be protected using the same mutex.
 +       */
 +      guard(mutex)(&sev_cmd_mutex);
 +
 +      /*
 +       * This API uses SNP_INIT_EX to transition allocated pages to HV_Fixed
 +       * page state, fail if SNP is already initialized.
 +       */
 +      if (sev->snp_initialized)
 +              return NULL;
 +
 +      /* Re-use freed pages that match the request */
 +      list_for_each_entry(entry, &snp_hv_fixed_pages, list) {
 +              /* Hypervisor fixed page allocator implements exact fit policy */
 +              if (entry->order == order && entry->free) {
 +                      entry->free = false;
 +                      memset(page_address(entry->page), 0,
 +                             (1 << entry->order) * PAGE_SIZE);
 +                      return entry->page;
 +              }
 +      }
 +
 +      page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
 +      if (!page)
 +              return NULL;
 +
 +      entry = kzalloc(sizeof(*entry), GFP_KERNEL);
 +      if (!entry) {
 +              __free_pages(page, order);
 +              return NULL;
 +      }
 +
 +      entry->page = page;
 +      entry->order = order;
 +      list_add_tail(&entry->list, &snp_hv_fixed_pages);
 +
 +      return page;
 +}
 +
 +void snp_free_hv_fixed_pages(struct page *page)
 +{
 +      struct psp_device *psp_master = psp_get_master_device();
 +      struct snp_hv_fixed_pages_entry *entry, *nentry;
 +
 +      if (!psp_master || !psp_master->sev_data)
 +              return;
 +
 +      /*
 +       * SNP_INIT_EX is protected by sev_cmd_mutex, therefore this list
 +       * also needs to be protected using the same mutex.
 +       */
 +      guard(mutex)(&sev_cmd_mutex);
 +
 +      list_for_each_entry_safe(entry, nentry, &snp_hv_fixed_pages, list) {
 +              if (entry->page != page)
 +                      continue;
 +
 +              /*
 +               * HV_FIXED page state cannot be changed until reboot
 +               * and they cannot be used by an SNP guest, so they cannot
 +               * be returned back to the page allocator.
 +               * Mark the pages as free internally to allow possible re-use.
 +               */
 +              if (entry->page_state == HV_FIXED) {
 +                      entry->free = true;
 +              } else {
 +                      __free_pages(page, entry->order);
 +                      list_del(&entry->list);
 +                      kfree(entry);
 +              }
 +              return;
 +      }
 +}
 +
 +static void snp_add_hv_fixed_pages(struct sev_device *sev, struct sev_data_range_list *range_list)
 +{
 +      struct snp_hv_fixed_pages_entry *entry;
 +      struct sev_data_range *range;
 +      int num_elements;
 +
 +      lockdep_assert_held(&sev_cmd_mutex);
 +
 +      if (list_empty(&snp_hv_fixed_pages))
 +              return;
 +
 +      num_elements = list_count_nodes(&snp_hv_fixed_pages) +
 +                     range_list->num_elements;
 +
 +      /*
 +       * Ensure the list of HV_FIXED pages that will be passed to firmware
 +       * do not exceed the page-sized argument buffer.
 +       */
 +      if (num_elements * sizeof(*range) + sizeof(*range_list) > PAGE_SIZE) {
 +              dev_warn(sev->dev, "Additional HV_Fixed pages cannot be accommodated, omitting\n");
 +              return;
 +      }
 +
 +      range = &range_list->ranges[range_list->num_elements];
 +      list_for_each_entry(entry, &snp_hv_fixed_pages, list) {
 +              range->base = page_to_pfn(entry->page) << PAGE_SHIFT;
 +              range->page_count = 1 << entry->order;
 +              range++;
 +      }
 +      range_list->num_elements = num_elements;
 +}
 +
 +static void snp_leak_hv_fixed_pages(void)
 +{
 +      struct snp_hv_fixed_pages_entry *entry;
 +
 +      /* List is protected by sev_cmd_mutex */
 +      lockdep_assert_held(&sev_cmd_mutex);
 +
 +      if (list_empty(&snp_hv_fixed_pages))
 +              return;
 +
 +      list_for_each_entry(entry, &snp_hv_fixed_pages, list)
 +              if (entry->page_state == HV_FIXED)
 +                      __snp_leak_pages(page_to_pfn(entry->page),
 +                                       1 << entry->order, false);
 +}
 +
+ bool sev_is_snp_ciphertext_hiding_supported(void)
+ {
+       struct psp_device *psp = psp_master;
+       struct sev_device *sev;
+       if (!psp || !psp->sev_data)
+               return false;
+       sev = psp->sev_data;
+       /*
+        * Feature information indicates if CipherTextHiding feature is
+        * supported by the SEV firmware and additionally platform status
+        * indicates if CipherTextHiding feature is enabled in the
+        * Platform BIOS.
+        */
+       return ((sev->snp_feat_info_0.ecx & SNP_CIPHER_TEXT_HIDING_SUPPORTED) &&
+                sev->snp_plat_status.ciphertext_hiding_cap);
+ }
+ EXPORT_SYMBOL_GPL(sev_is_snp_ciphertext_hiding_supported);
+ static int snp_get_platform_data(struct sev_device *sev, int *error)
+ {
+       struct sev_data_snp_feature_info snp_feat_info;
+       struct snp_feature_info *feat_info;
+       struct sev_data_snp_addr buf;
+       struct page *page;
+       int rc;
+       /*
+        * This function is expected to be called before SNP is
+        * initialized.
+        */
+       if (sev->snp_initialized)
+               return -EINVAL;
+       buf.address = __psp_pa(&sev->snp_plat_status);
+       rc = sev_do_cmd(SEV_CMD_SNP_PLATFORM_STATUS, &buf, error);
+       if (rc) {
+               dev_err(sev->dev, "SNP PLATFORM_STATUS command failed, ret = %d, error = %#x\n",
+                       rc, *error);
+               return rc;
+       }
+       sev->api_major = sev->snp_plat_status.api_major;
+       sev->api_minor = sev->snp_plat_status.api_minor;
+       sev->build = sev->snp_plat_status.build_id;
+       /*
+        * Do feature discovery of the currently loaded firmware,
+        * and cache feature information from CPUID 0x8000_0024,
+        * sub-function 0.
+        */
+       if (!sev->snp_plat_status.feature_info)
+               return 0;
+       /*
+        * Use dynamically allocated structure for the SNP_FEATURE_INFO
+        * command to ensure structure is 8-byte aligned, and does not
+        * cross a page boundary.
+        */
+       page = alloc_page(GFP_KERNEL);
+       if (!page)
+               return -ENOMEM;
+       feat_info = page_address(page);
+       snp_feat_info.length = sizeof(snp_feat_info);
+       snp_feat_info.ecx_in = 0;
+       snp_feat_info.feature_info_paddr = __psp_pa(feat_info);
+       rc = sev_do_cmd(SEV_CMD_SNP_FEATURE_INFO, &snp_feat_info, error);
+       if (!rc)
+               sev->snp_feat_info_0 = *feat_info;
+       else
+               dev_err(sev->dev, "SNP FEATURE_INFO command failed, ret = %d, error = %#x\n",
+                       rc, *error);
+       __free_page(page);
+       return rc;
+ }
  static int snp_filter_reserved_mem_regions(struct resource *rs, void *arg)
  {
        struct sev_data_range_list *range_list = arg;
@@@ -1338,13 -1248,13 +1423,19 @@@ static int __sev_snp_init_locked(int *e
                        return rc;
                }
  
 +              /*
 +               * Add HV_Fixed pages from other PSP sub-devices, such as SFS to the
 +               * HV_Fixed page list.
 +               */
 +              snp_add_hv_fixed_pages(sev, snp_range_list);
 +
                memset(&data, 0, sizeof(data));
+               if (max_snp_asid) {
+                       data.ciphertext_hiding_en = 1;
+                       data.max_snp_asid = max_snp_asid;
+               }
                data.init_rmp = 1;
                data.list_paddr_en = 1;
                data.list_paddr = __psp_pa(snp_range_list);
@@@ -1527,21 -1436,12 +1618,21 @@@ static int _sev_platform_init_locked(st
        if (!psp_master || !psp_master->sev_data)
                return -ENODEV;
  
 +      /*
 +       * Skip SNP/SEV initialization under a kdump kernel as SEV/SNP
 +       * may already be initialized in the previous kernel. Since no
 +       * SNP/SEV guests are run under a kdump kernel, there is no
 +       * need to initialize SNP or SEV during kdump boot.
 +       */
 +      if (is_kdump_kernel())
 +              return 0;
 +
        sev = psp_master->sev_data;
  
-       if (sev->state == SEV_STATE_INIT)
+       if (sev->sev_plat_status.state == SEV_STATE_INIT)
                return 0;
  
-       rc = __sev_snp_init_locked(&args->error);
+       rc = __sev_snp_init_locked(&args->error, args->max_snp_asid);
        if (rc && rc != -ENODEV)
                return rc;
  
Simple merge
Simple merge