[PATCH v9 3/3] x86/snp: Convert shared memory back to private on kexec

Tom Lendacky thomas.lendacky at amd.com
Mon Jun 24 08:18:18 PDT 2024


On 6/20/24 17:23, Ashish Kalra wrote:
> From: Ashish Kalra <ashish.kalra at amd.com>
> 
> SNP guests allocate shared buffers to perform I/O. It is done by
> allocating pages normally from the buddy allocator and converting them
> to shared with set_memory_decrypted().
> 
> The second kernel has no idea what memory is converted this way. It only
> sees E820_TYPE_RAM.
> 
> Accessing shared memory via private mapping will cause unrecoverable RMP
> page-faults.
> 
> On kexec walk direct mapping and convert all shared memory back to
> private. It makes all RAM private again and second kernel may use it
> normally. Additionally for SNP guests convert all bss decrypted section
> pages back to private.
> 
> The conversion occurs in two steps: stopping new conversions and
> unsharing all memory. In the case of normal kexec, the stopping of
> conversions takes place while scheduling is still functioning. This
> allows for waiting until any ongoing conversions are finished. The
> second step is carried out when all CPUs except one are inactive and
> interrupts are disabled. This prevents any conflicts with code that may
> access shared memory.
> 
> Signed-off-by: Ashish Kalra <ashish.kalra at amd.com>

The pr_debug() calls don't make a lot of sense (and one appears to be in
the wrong location given what it says vs what is done) and should
probably be removed.

Otherwise:

Reviewed-by: Tom Lendacky <thomas.lendacky at amd.com>

...

> +	/* Check for GHCB for being part of a PMD range. */
> +	if ((unsigned long)ghcb >= addr &&
> +	    (unsigned long)ghcb <= (addr + (pages * PAGE_SIZE))) {
> +		/*
> +		 * Ensure that the current cpu's GHCB is made private
> +		 * at the end of unshared loop so that we continue to use the
> +		 * optimized GHCB protocol and not force the switch to
> +		 * MSR protocol till the very end.
> +		 */
> +		pr_debug("setting boot_ghcb to NULL for this cpu ghcb\n");
> +		kexec_last_addr_to_make_private = addr;
> +		return true;
> +	}

...

> +		/*
> +		 * Switch to using the MSR protocol to change this cpu's
> +		 * GHCB to private.
> +		 * All the per-cpu GHCBs have been switched back to private,
> +		 * so can't do any more GHCB calls to the hypervisor beyond
> +		 * this point till the kexec kernel starts running.
> +		 */
> +		boot_ghcb = NULL;
> +		sev_cfg.ghcbs_initialized = false;
> +
> +		pr_debug("boot ghcb 0x%lx\n", kexec_last_addr_to_make_private);
> +		pte = lookup_address(kexec_last_addr_to_make_private, &level);
> +		size = page_level_size(level);
> +		set_pte_enc(pte, level, (void *)kexec_last_addr_to_make_private);
> +		snp_set_memory_private(kexec_last_addr_to_make_private, (size / PAGE_SIZE));
> +	}
> +}



More information about the kexec mailing list