|  | @@ -220,6 +220,29 @@ static int hv_check_features ( struct hv_hypervisor *hv ) {
 | 
		
	
		
			
			| 220 | 220 |  	return 0;
 | 
		
	
		
			
			| 221 | 221 |  }
 | 
		
	
		
			
			| 222 | 222 |  
 | 
		
	
		
			
			|  | 223 | +/**
 | 
		
	
		
			
			|  | 224 | + * Check that Gen 2 UEFI firmware is not running
 | 
		
	
		
			
			|  | 225 | + *
 | 
		
	
		
			
			|  | 226 | + * @v hv		Hyper-V hypervisor
 | 
		
	
		
			
			|  | 227 | + * @ret rc		Return status code
 | 
		
	
		
			
			|  | 228 | + *
 | 
		
	
		
			
			|  | 229 | + * We must not steal ownership from the Gen 2 UEFI firmware, since
 | 
		
	
		
			
			|  | 230 | + * doing so will cause an immediate crash.  Avoid this by checking for
 | 
		
	
		
			
			|  | 231 | + * the guest OS identity known to be used by the Gen 2 UEFI firmware.
 | 
		
	
		
			
			|  | 232 | + */
 | 
		
	
		
			
			|  | 233 | +static int hv_check_uefi ( struct hv_hypervisor *hv ) {
 | 
		
	
		
			
			|  | 234 | +	uint64_t guest_os_id;
 | 
		
	
		
			
			|  | 235 | +
 | 
		
	
		
			
			|  | 236 | +	/* Check for UEFI firmware's guest OS identity */
 | 
		
	
		
			
			|  | 237 | +	guest_os_id = rdmsr ( HV_X64_MSR_GUEST_OS_ID );
 | 
		
	
		
			
			|  | 238 | +	if ( guest_os_id == HV_GUEST_OS_ID_UEFI ) {
 | 
		
	
		
			
			|  | 239 | +		DBGC ( hv, "HV %p is owned by UEFI firmware\n", hv );
 | 
		
	
		
			
			|  | 240 | +		return -ENOTSUP;
 | 
		
	
		
			
			|  | 241 | +	}
 | 
		
	
		
			
			|  | 242 | +
 | 
		
	
		
			
			|  | 243 | +	return 0;
 | 
		
	
		
			
			|  | 244 | +}
 | 
		
	
		
			
			|  | 245 | +
 | 
		
	
		
			
			| 223 | 246 |  /**
 | 
		
	
		
			
			| 224 | 247 |   * Map hypercall page
 | 
		
	
		
			
			| 225 | 248 |   *
 | 
		
	
	
		
			
			|  | @@ -556,6 +579,10 @@ static int hv_probe ( struct root_device *rootdev ) {
 | 
		
	
		
			
			| 556 | 579 |  	if ( ( rc = hv_check_features ( hv ) ) != 0 )
 | 
		
	
		
			
			| 557 | 580 |  		goto err_check_features;
 | 
		
	
		
			
			| 558 | 581 |  
 | 
		
	
		
			
			|  | 582 | +	/* Check that Gen 2 UEFI firmware is not running */
 | 
		
	
		
			
			|  | 583 | +	if ( ( rc = hv_check_uefi ( hv ) ) != 0 )
 | 
		
	
		
			
			|  | 584 | +		goto err_check_uefi;
 | 
		
	
		
			
			|  | 585 | +
 | 
		
	
		
			
			| 559 | 586 |  	/* Allocate pages */
 | 
		
	
		
			
			| 560 | 587 |  	if ( ( rc = hv_alloc_pages ( hv, &hv->hypercall, &hv->synic.message,
 | 
		
	
		
			
			| 561 | 588 |  				     &hv->synic.event, NULL ) ) != 0 )
 | 
		
	
	
		
			
			|  | @@ -587,6 +614,7 @@ static int hv_probe ( struct root_device *rootdev ) {
 | 
		
	
		
			
			| 587 | 614 |  	hv_free_pages ( hv, hv->hypercall, hv->synic.message, hv->synic.event,
 | 
		
	
		
			
			| 588 | 615 |  			NULL );
 | 
		
	
		
			
			| 589 | 616 |   err_alloc_pages:
 | 
		
	
		
			
			|  | 617 | + err_check_uefi:
 | 
		
	
		
			
			| 590 | 618 |   err_check_features:
 | 
		
	
		
			
			| 591 | 619 |  	free ( hv );
 | 
		
	
		
			
			| 592 | 620 |   err_alloc:
 |