forked from mirrors/linux
		
	virt: acrn: Introduce an interface for Service VM to control vCPU
ACRN supports partition mode to achieve real-time requirements. In partition mode, a CPU core can be dedicated to a vCPU of User VM. The local APIC of the dedicated CPU core can be passthrough to the User VM. The Service VM controls the assignment of the CPU cores. Introduce an interface for the Service VM to remove the control of CPU core from hypervisor perspective so that the CPU core can be a dedicated CPU core of User VM. Cc: Zhi Wang <zhi.a.wang@intel.com> Cc: Zhenyu Wang <zhenyuw@linux.intel.com> Cc: Yu Wang <yu1.wang@intel.com> Cc: Reinette Chatre <reinette.chatre@intel.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Reviewed-by: Zhi Wang <zhi.a.wang@intel.com> Reviewed-by: Reinette Chatre <reinette.chatre@intel.com> Signed-off-by: Shuo Liu <shuo.a.liu@intel.com> Link: https://lore.kernel.org/r/20210207031040.49576-18-shuo.a.liu@intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
		
							parent
							
								
									aa3b483ff1
								
							
						
					
					
						commit
						279dcf693a
					
				
					 2 changed files with 62 additions and 0 deletions
				
			
		|  | @ -9,6 +9,7 @@ | ||||||
|  *	Yakui Zhao <yakui.zhao@intel.com> |  *	Yakui Zhao <yakui.zhao@intel.com> | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #include <linux/cpu.h> | ||||||
| #include <linux/io.h> | #include <linux/io.h> | ||||||
| #include <linux/mm.h> | #include <linux/mm.h> | ||||||
| #include <linux/module.h> | #include <linux/module.h> | ||||||
|  | @ -371,6 +372,52 @@ static int acrn_dev_release(struct inode *inode, struct file *filp) | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static ssize_t remove_cpu_store(struct device *dev, | ||||||
|  | 				struct device_attribute *attr, | ||||||
|  | 				const char *buf, size_t count) | ||||||
|  | { | ||||||
|  | 	u64 cpu, lapicid; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	if (kstrtoull(buf, 0, &cpu) < 0) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	if (cpu >= num_possible_cpus() || cpu == 0 || !cpu_is_hotpluggable(cpu)) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	if (cpu_online(cpu)) | ||||||
|  | 		remove_cpu(cpu); | ||||||
|  | 
 | ||||||
|  | 	lapicid = cpu_data(cpu).apicid; | ||||||
|  | 	dev_dbg(dev, "Try to remove cpu %lld with lapicid %lld\n", cpu, lapicid); | ||||||
|  | 	ret = hcall_sos_remove_cpu(lapicid); | ||||||
|  | 	if (ret < 0) { | ||||||
|  | 		dev_err(dev, "Failed to remove cpu %lld!\n", cpu); | ||||||
|  | 		goto fail_remove; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return count; | ||||||
|  | 
 | ||||||
|  | fail_remove: | ||||||
|  | 	add_cpu(cpu); | ||||||
|  | 	return ret; | ||||||
|  | } | ||||||
|  | static DEVICE_ATTR_WO(remove_cpu); | ||||||
|  | 
 | ||||||
|  | static struct attribute *acrn_attrs[] = { | ||||||
|  | 	&dev_attr_remove_cpu.attr, | ||||||
|  | 	NULL | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static struct attribute_group acrn_attr_group = { | ||||||
|  | 	.attrs = acrn_attrs, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static const struct attribute_group *acrn_attr_groups[] = { | ||||||
|  | 	&acrn_attr_group, | ||||||
|  | 	NULL | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| static const struct file_operations acrn_fops = { | static const struct file_operations acrn_fops = { | ||||||
| 	.owner		= THIS_MODULE, | 	.owner		= THIS_MODULE, | ||||||
| 	.open		= acrn_dev_open, | 	.open		= acrn_dev_open, | ||||||
|  | @ -382,6 +429,7 @@ struct miscdevice acrn_dev = { | ||||||
| 	.minor	= MISC_DYNAMIC_MINOR, | 	.minor	= MISC_DYNAMIC_MINOR, | ||||||
| 	.name	= "acrn_hsm", | 	.name	= "acrn_hsm", | ||||||
| 	.fops	= &acrn_fops, | 	.fops	= &acrn_fops, | ||||||
|  | 	.groups	= acrn_attr_groups, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static int __init hsm_init(void) | static int __init hsm_init(void) | ||||||
|  |  | ||||||
|  | @ -13,6 +13,9 @@ | ||||||
| 
 | 
 | ||||||
| #define HC_ID 0x80UL | #define HC_ID 0x80UL | ||||||
| 
 | 
 | ||||||
|  | #define HC_ID_GEN_BASE			0x0UL | ||||||
|  | #define HC_SOS_REMOVE_CPU		_HC_ID(HC_ID, HC_ID_GEN_BASE + 0x01) | ||||||
|  | 
 | ||||||
| #define HC_ID_VM_BASE			0x10UL | #define HC_ID_VM_BASE			0x10UL | ||||||
| #define HC_CREATE_VM			_HC_ID(HC_ID, HC_ID_VM_BASE + 0x00) | #define HC_CREATE_VM			_HC_ID(HC_ID, HC_ID_VM_BASE + 0x00) | ||||||
| #define HC_DESTROY_VM			_HC_ID(HC_ID, HC_ID_VM_BASE + 0x01) | #define HC_DESTROY_VM			_HC_ID(HC_ID, HC_ID_VM_BASE + 0x01) | ||||||
|  | @ -42,6 +45,17 @@ | ||||||
| #define HC_ID_PM_BASE			0x80UL | #define HC_ID_PM_BASE			0x80UL | ||||||
| #define HC_PM_GET_CPU_STATE		_HC_ID(HC_ID, HC_ID_PM_BASE + 0x00) | #define HC_PM_GET_CPU_STATE		_HC_ID(HC_ID, HC_ID_PM_BASE + 0x00) | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * hcall_sos_remove_cpu() - Remove a vCPU of Service VM | ||||||
|  |  * @cpu: The vCPU to be removed | ||||||
|  |  * | ||||||
|  |  * Return: 0 on success, <0 on failure | ||||||
|  |  */ | ||||||
|  | static inline long hcall_sos_remove_cpu(u64 cpu) | ||||||
|  | { | ||||||
|  | 	return acrn_hypercall1(HC_SOS_REMOVE_CPU, cpu); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * hcall_create_vm() - Create a User VM |  * hcall_create_vm() - Create a User VM | ||||||
|  * @vminfo:	Service VM GPA of info of User VM creation |  * @vminfo:	Service VM GPA of info of User VM creation | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Shuo Liu
						Shuo Liu