Commit a5ddb745 authored by Michael Kelley's avatar Michael Kelley Committed by Wei Liu
Browse files

Drivers: hv: vmbus: Remove second mapping of VMBus monitor pages



With changes to how Hyper-V guest VMs flip memory between private
(encrypted) and shared (decrypted), creating a second kernel virtual
mapping for shared memory is no longer necessary.  Everything needed
for the transition to shared is handled by set_memory_decrypted().

As such, remove the code to create and manage the second
mapping for VMBus monitor pages. Because set_memory_decrypted()
and set_memory_encrypted() are no-ops in normal VMs, it's
not even necessary to test for being in a Confidential VM
(a.k.a., "Isolation VM").

Signed-off-by: default avatarMichael Kelley <mikelley@microsoft.com>
Reviewed-by: default avatarTianyu Lan <Tianyu.Lan@microsoft.com>
Link: https://lore.kernel.org/r/1679838727-87310-9-git-send-email-mikelley@microsoft.com


Signed-off-by: default avatarWei Liu <wei.liu@kernel.org>
parent 0459ff48
Loading
Loading
Loading
Loading
+28 −85
Original line number Diff line number Diff line
@@ -104,8 +104,14 @@ int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo, u32 version)
		vmbus_connection.msg_conn_id = VMBUS_MESSAGE_CONNECTION_ID;
	}

	msg->monitor_page1 = vmbus_connection.monitor_pages_pa[0];
	msg->monitor_page2 = vmbus_connection.monitor_pages_pa[1];
	/*
	 * shared_gpa_boundary is zero in non-SNP VMs, so it's safe to always
	 * bitwise OR it
	 */
	msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]) |
				ms_hyperv.shared_gpa_boundary;
	msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]) |
				ms_hyperv.shared_gpa_boundary;

	msg->target_vcpu = hv_cpu_number_to_vp_number(VMBUS_CONNECT_CPU);

@@ -219,72 +225,27 @@ int vmbus_connect(void)
	 * Setup the monitor notification facility. The 1st page for
	 * parent->child and the 2nd page for child->parent
	 */
	vmbus_connection.monitor_pages[0] = (void *)hv_alloc_hyperv_zeroed_page();
	vmbus_connection.monitor_pages[1] = (void *)hv_alloc_hyperv_zeroed_page();
	vmbus_connection.monitor_pages[0] = (void *)hv_alloc_hyperv_page();
	vmbus_connection.monitor_pages[1] = (void *)hv_alloc_hyperv_page();
	if ((vmbus_connection.monitor_pages[0] == NULL) ||
	    (vmbus_connection.monitor_pages[1] == NULL)) {
		ret = -ENOMEM;
		goto cleanup;
	}

	vmbus_connection.monitor_pages_original[0]
		= vmbus_connection.monitor_pages[0];
	vmbus_connection.monitor_pages_original[1]
		= vmbus_connection.monitor_pages[1];
	vmbus_connection.monitor_pages_pa[0]
		= virt_to_phys(vmbus_connection.monitor_pages[0]);
	vmbus_connection.monitor_pages_pa[1]
		= virt_to_phys(vmbus_connection.monitor_pages[1]);

	if (hv_is_isolation_supported()) {
	ret = set_memory_decrypted((unsigned long)
					   vmbus_connection.monitor_pages[0],
					   1);
				vmbus_connection.monitor_pages[0], 1);
	ret |= set_memory_decrypted((unsigned long)
					    vmbus_connection.monitor_pages[1],
					    1);
				vmbus_connection.monitor_pages[1], 1);
	if (ret)
		goto cleanup;

	/*
		 * Isolation VM with AMD SNP needs to access monitor page via
		 * address space above shared gpa boundary.
		 */
		if (hv_isolation_type_snp()) {
			vmbus_connection.monitor_pages_pa[0] +=
				ms_hyperv.shared_gpa_boundary;
			vmbus_connection.monitor_pages_pa[1] +=
				ms_hyperv.shared_gpa_boundary;

			vmbus_connection.monitor_pages[0]
				= memremap(vmbus_connection.monitor_pages_pa[0],
					   HV_HYP_PAGE_SIZE,
					   MEMREMAP_WB);
			if (!vmbus_connection.monitor_pages[0]) {
				ret = -ENOMEM;
				goto cleanup;
			}

			vmbus_connection.monitor_pages[1]
				= memremap(vmbus_connection.monitor_pages_pa[1],
					   HV_HYP_PAGE_SIZE,
					   MEMREMAP_WB);
			if (!vmbus_connection.monitor_pages[1]) {
				ret = -ENOMEM;
				goto cleanup;
			}
		}

		/*
		 * Set memory host visibility hvcall smears memory
		 * and so zero monitor pages here.
	 * Set_memory_decrypted() will change the memory contents if
	 * decryption occurs, so zero monitor pages here.
	 */
		memset(vmbus_connection.monitor_pages[0], 0x00,
		       HV_HYP_PAGE_SIZE);
		memset(vmbus_connection.monitor_pages[1], 0x00,
		       HV_HYP_PAGE_SIZE);

	}
	memset(vmbus_connection.monitor_pages[0], 0x00, HV_HYP_PAGE_SIZE);
	memset(vmbus_connection.monitor_pages[1], 0x00, HV_HYP_PAGE_SIZE);

	msginfo = kzalloc(sizeof(*msginfo) +
			  sizeof(struct vmbus_channel_initiate_contact),
@@ -376,30 +337,12 @@ void vmbus_disconnect(void)
		vmbus_connection.int_page = NULL;
	}

	if (hv_is_isolation_supported()) {
		/*
		 * memunmap() checks input address is ioremap address or not
		 * inside. It doesn't unmap any thing in the non-SNP CVM and
		 * so not check CVM type here.
		 */
		memunmap(vmbus_connection.monitor_pages[0]);
		memunmap(vmbus_connection.monitor_pages[1]);

		set_memory_encrypted((unsigned long)
			vmbus_connection.monitor_pages_original[0],
			1);
		set_memory_encrypted((unsigned long)
			vmbus_connection.monitor_pages_original[1],
			1);
	}
	set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[0], 1);
	set_memory_encrypted((unsigned long)vmbus_connection.monitor_pages[1], 1);

	hv_free_hyperv_page((unsigned long)
		vmbus_connection.monitor_pages_original[0]);
	hv_free_hyperv_page((unsigned long)
		vmbus_connection.monitor_pages_original[1]);
	vmbus_connection.monitor_pages_original[0] =
	hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[0]);
	hv_free_hyperv_page((unsigned long)vmbus_connection.monitor_pages[1]);
	vmbus_connection.monitor_pages[0] = NULL;
	vmbus_connection.monitor_pages_original[1] =
	vmbus_connection.monitor_pages[1] = NULL;
}

+0 −2
Original line number Diff line number Diff line
@@ -241,8 +241,6 @@ struct vmbus_connection {
	 * is child->parent notification
	 */
	struct hv_monitor_page *monitor_pages[2];
	void *monitor_pages_original[2];
	phys_addr_t monitor_pages_pa[2];
	struct list_head chn_msg_list;
	spinlock_t channelmsg_lock;