Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os 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>

authored by

Shuo Liu and committed by
Greg Kroah-Hartman
279dcf69 aa3b483f

+62
+48
drivers/virt/acrn/hsm.c
··· 9 9 * Yakui Zhao <yakui.zhao@intel.com> 10 10 */ 11 11 12 + #include <linux/cpu.h> 12 13 #include <linux/io.h> 13 14 #include <linux/mm.h> 14 15 #include <linux/module.h> ··· 372 371 return 0; 373 372 } 374 373 374 + static ssize_t remove_cpu_store(struct device *dev, 375 + struct device_attribute *attr, 376 + const char *buf, size_t count) 377 + { 378 + u64 cpu, lapicid; 379 + int ret; 380 + 381 + if (kstrtoull(buf, 0, &cpu) < 0) 382 + return -EINVAL; 383 + 384 + if (cpu >= num_possible_cpus() || cpu == 0 || !cpu_is_hotpluggable(cpu)) 385 + return -EINVAL; 386 + 387 + if (cpu_online(cpu)) 388 + remove_cpu(cpu); 389 + 390 + lapicid = cpu_data(cpu).apicid; 391 + dev_dbg(dev, "Try to remove cpu %lld with lapicid %lld\n", cpu, lapicid); 392 + ret = hcall_sos_remove_cpu(lapicid); 393 + if (ret < 0) { 394 + dev_err(dev, "Failed to remove cpu %lld!\n", cpu); 395 + goto fail_remove; 396 + } 397 + 398 + return count; 399 + 400 + fail_remove: 401 + add_cpu(cpu); 402 + return ret; 403 + } 404 + static DEVICE_ATTR_WO(remove_cpu); 405 + 406 + static struct attribute *acrn_attrs[] = { 407 + &dev_attr_remove_cpu.attr, 408 + NULL 409 + }; 410 + 411 + static struct attribute_group acrn_attr_group = { 412 + .attrs = acrn_attrs, 413 + }; 414 + 415 + static const struct attribute_group *acrn_attr_groups[] = { 416 + &acrn_attr_group, 417 + NULL 418 + }; 419 + 375 420 static const struct file_operations acrn_fops = { 376 421 .owner = THIS_MODULE, 377 422 .open = acrn_dev_open, ··· 429 382 .minor = MISC_DYNAMIC_MINOR, 430 383 .name = "acrn_hsm", 431 384 .fops = &acrn_fops, 385 + .groups = acrn_attr_groups, 432 386 }; 433 387 434 388 static int __init hsm_init(void)
+14
drivers/virt/acrn/hypercall.h
··· 13 13 14 14 #define HC_ID 0x80UL 15 15 16 + #define HC_ID_GEN_BASE 0x0UL 17 + #define HC_SOS_REMOVE_CPU _HC_ID(HC_ID, HC_ID_GEN_BASE + 0x01) 18 + 16 19 #define HC_ID_VM_BASE 0x10UL 17 20 #define HC_CREATE_VM _HC_ID(HC_ID, HC_ID_VM_BASE + 0x00) 18 21 #define HC_DESTROY_VM _HC_ID(HC_ID, HC_ID_VM_BASE + 0x01) ··· 44 41 45 42 #define HC_ID_PM_BASE 0x80UL 46 43 #define HC_PM_GET_CPU_STATE _HC_ID(HC_ID, HC_ID_PM_BASE + 0x00) 44 + 45 + /** 46 + * hcall_sos_remove_cpu() - Remove a vCPU of Service VM 47 + * @cpu: The vCPU to be removed 48 + * 49 + * Return: 0 on success, <0 on failure 50 + */ 51 + static inline long hcall_sos_remove_cpu(u64 cpu) 52 + { 53 + return acrn_hypercall1(HC_SOS_REMOVE_CPU, cpu); 54 + } 47 55 48 56 /** 49 57 * hcall_create_vm() - Create a User VM