diff options
Diffstat (limited to 'drivers/hv/connection.c')
| -rw-r--r-- | drivers/hv/connection.c | 117 | 
1 files changed, 32 insertions, 85 deletions
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c index 9dc27e5d367a..5978e9dbc286 100644 --- a/drivers/hv/connection.c +++ b/drivers/hv/connection.c @@ -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); -		ret |= set_memory_decrypted((unsigned long) -					    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. -		 */ -		memset(vmbus_connection.monitor_pages[0], 0x00, -		       HV_HYP_PAGE_SIZE); -		memset(vmbus_connection.monitor_pages[1], 0x00, -		       HV_HYP_PAGE_SIZE); +	ret = set_memory_decrypted((unsigned long) +				vmbus_connection.monitor_pages[0], 1); +	ret |= set_memory_decrypted((unsigned long) +				vmbus_connection.monitor_pages[1], 1); +	if (ret) +		goto cleanup; -	} +	/* +	 * 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);  	msginfo = kzalloc(sizeof(*msginfo) +  			  sizeof(struct vmbus_channel_initiate_contact), @@ -376,31 +337,13 @@ 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] = -		vmbus_connection.monitor_pages[0] = NULL; -	vmbus_connection.monitor_pages_original[1] = -		vmbus_connection.monitor_pages[1] = NULL; +	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[1] = NULL;  }  /* @@ -409,6 +352,10 @@ void vmbus_disconnect(void)   */  struct vmbus_channel *relid2channel(u32 relid)  { +	if (vmbus_connection.channels == NULL) { +		pr_warn_once("relid2channel: relid=%d: No channels mapped!\n", relid); +		return NULL; +	}  	if (WARN_ON(relid >= MAX_CHANNEL_RELIDS))  		return NULL;  	return READ_ONCE(vmbus_connection.channels[relid]);  |