linux-next: manual merge of the tip tree with the crypto tree

Mark Brown posted 1 patch 1 week, 5 days ago
linux-next: manual merge of the tip tree with the crypto tree
Posted by Mark Brown 1 week, 5 days ago
Hi all,

Today's linux-next merge of the tip tree got a conflict in:

  drivers/crypto/ccp/sev-dev.c

between commits:

  45d59bd4a3e0f ("crypto: ccp - Introduce new API interface to indicate SEV-SNP Ciphertext hiding feature")
  33cfb80d1910b ("crypto: ccp - Add support for SNP_FEATURE_INFO command")

from the crypto tree and commit:

  e09701dcdd9ca ("crypto: ccp - Add new HV-Fixed page allocation/free API")

from the tip tree.

I fixed it up (see below) and can carry the fix as necessary. This
is now fixed as far as linux-next is concerned, but any non trivial
conflicts should be mentioned to your upstream maintainer when your tree
is submitted for merging.  You may also want to consider cooperating
with the maintainer of the conflicting tree to minimise any particularly
complex conflicts.


diff --cc drivers/crypto/ccp/sev-dev.c
index d3465c251eb0a,f7b9c6547e18f..0000000000000
--- a/drivers/crypto/ccp/sev-dev.c
+++ b/drivers/crypto/ccp/sev-dev.c
@@@ -1077,88 -1088,165 +1092,247 @@@ static void snp_set_hsave_pa(void *arg
  	wrmsrq(MSR_VM_HSAVE_PA, 0);
  }
  
 +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;
 +}
 +
+ /* 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);
+ }
+ 
  static int snp_filter_reserved_mem_regions(struct resource *rs, void *arg)
  {
  	struct sev_data_range_list *range_list = arg;
@@@ -1249,13 -1337,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);
Re: linux-next: manual merge of the tip tree with the crypto tree
Posted by Borislav Petkov 1 week, 5 days ago
On Fri, Sep 19, 2025 at 02:31:18PM +0100, Mark Brown wrote:
> Hi all,
> 
> Today's linux-next merge of the tip tree got a conflict in:
> 
>   drivers/crypto/ccp/sev-dev.c
> 
> between commits:
> 
>   45d59bd4a3e0f ("crypto: ccp - Introduce new API interface to indicate SEV-SNP Ciphertext hiding feature")
>   33cfb80d1910b ("crypto: ccp - Add support for SNP_FEATURE_INFO command")
> 
> from the crypto tree and commit:
> 
>   e09701dcdd9ca ("crypto: ccp - Add new HV-Fixed page allocation/free API")

Pff, in hindsight those should probably all go through the crypto tree so that
there's no unnecessary conflicts.

Herbert, lemme know if I should undo them here and you take all three:

648dbccc03a0 crypto: ccp - Add AMD Seamless Firmware Servicing (SFS) driver
e09701dcdd9c crypto: ccp - Add new HV-Fixed page allocation/free API
e4c00c4ce2aa x86/sev: Add new dump_rmp parameter to snp_leak_pages() API

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette
Re: linux-next: manual merge of the tip tree with the crypto tree
Posted by Herbert Xu 1 week, 5 days ago
On Fri, Sep 19, 2025 at 10:43:55PM +0200, Borislav Petkov wrote:
>
> Pff, in hindsight those should probably all go through the crypto tree so that
> there's no unnecessary conflicts.
> 
> Herbert, lemme know if I should undo them here and you take all three:
> 
> 648dbccc03a0 crypto: ccp - Add AMD Seamless Firmware Servicing (SFS) driver
> e09701dcdd9c crypto: ccp - Add new HV-Fixed page allocation/free API
> e4c00c4ce2aa x86/sev: Add new dump_rmp parameter to snp_leak_pages() API

I think either way we will end up with conflicts.  If I merge
them then we will get conflicts in x86/sev.  If you merge them
then we get the conflicts in drivers/crypto.

As the conflicts seem to be straightforward, how about we just
keep things as it is and mention it to Linus when the merge window
opens?

Cheers,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt