Commit 21882838 authored by Xin Jiang's avatar Xin Jiang Committed by hanliyang
Browse files

x86: Add support for changing the memory attribute for CSV3 guest

hygon inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IAYGKY


CVE: NA

---------------------------

Add support for changing the memory to private or shared memory for
multiple pages if CSV3 is active.

When CSV3 guest wants to share data with host like SWIOTLB or change
the unused shared memory to private memory, it must perform an secure
call command to the secure processor to update mapping in nested page
table.

Signed-off-by: default avatarXin Jiang <jiangxin@hygon.cn>
Signed-off-by: default avatarhanliyang <hanliyang@hygon.cn>
parent 5cd48014
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@ void __init csv_early_update_memory_dec(u64 vaddr, u64 pages);

void __init csv_early_memory_enc_dec(u64 vaddr, u64 size, bool enc);

void csv_memory_enc_dec(u64 vaddr, u64 pages, bool enc);

#else	/* !CONFIG_HYGON_CSV */

static inline bool csv3_active(void) { return false; }
@@ -76,6 +78,8 @@ static inline void __init csv_early_update_memory_dec(u64 vaddr, u64 pages) { }
static inline void __init csv_early_memory_enc_dec(u64 vaddr, u64 size,
						   bool enc) { }

static inline void csv_memory_enc_dec(u64 vaddr, u64 pages, bool enc) { }

#endif	/* CONFIG_HYGON_CSV */

#endif	/* __ASSEMBLY__ */
+52 −0
Original line number Diff line number Diff line
@@ -172,6 +172,50 @@ static void __init __csv3_early_secure_call(u64 base_address, u64 num_pages,
	early_secure_call_page_idx ^= 1;
}

static void csv3_secure_call(u64 base_address, u64 num_pages,
			     enum csv3_secure_command_type cmd_type)
{
	u32 cmd_ack;
	struct secure_call_pages *data;
	struct csv3_secure_call_cmd *page_rd;
	struct csv3_secure_call_cmd *page_wr;
	int page_idx;
	int cpu;

	preempt_disable();

	cpu = smp_processor_id();
	data = per_cpu(secure_call_data, cpu);
	page_idx = per_cpu(secure_call_page_idx, cpu);

	if (page_idx == 0) {
		page_rd = &data->page_a;
		page_wr = &data->page_b;
	} else {
		page_rd = &data->page_b;
		page_wr = &data->page_a;
	}

	while (1) {
		page_wr->cmd_type = (u32)cmd_type;
		page_wr->nums = 1;
		page_wr->entry[0].base_address = base_address;
		page_wr->entry[0].size = num_pages << PAGE_SHIFT;

		/*
		 * Write command in page_wr must be done before retrieve cmd
		 * ack from page_rd, and it is ensured by the smp_mb below.
		 */
		smp_mb();

		cmd_ack = page_rd->cmd_type;
		if (cmd_ack != cmd_type)
			break;
	}

	per_cpu(secure_call_page_idx, cpu) ^= 1;
	preempt_enable();
}

static void __csv3_memory_enc_dec(csv3_secure_call_func secure_call, u64 vaddr,
				  u64 pages, bool enc)
@@ -233,3 +277,11 @@ void __init csv_early_memory_enc_dec(u64 vaddr, u64 size, bool enc)
	__csv3_memory_enc_dec(__csv3_early_secure_call, vaddr & PAGE_MASK,
			      npages, enc);
}

void csv_memory_enc_dec(u64 vaddr, u64 pages, bool enc)
{
	if (!csv3_active())
		return;

	__csv3_memory_enc_dec(csv3_secure_call, vaddr & PAGE_MASK, pages, enc);
}
+8 −0
Original line number Diff line number Diff line
@@ -345,6 +345,14 @@ static bool amd_enc_status_change_finish(unsigned long vaddr, int npages, bool e
	if (!cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
		enc_dec_hypercall(vaddr, npages << PAGE_SHIFT, enc);

	/*
	 * On CSV3, the shared and private page attr changes should be managed
	 * by secure processor. Private pages live in isolated memory region,
	 * while shared pages live out of isolated memory region.
	 */
	if (csv3_active())
		csv_memory_enc_dec(vaddr, npages, enc);

	return true;
}