aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Upton <oliver.upton@linux.dev>2023-08-19 19:40:55 +0000
committerOliver Upton <oliver.upton@linux.dev>2023-08-20 02:23:45 +0000
commit097e641fb5fdf22458248af07b7c0456f992c06e (patch)
tree7c333e6beb26eec0d9dff68eb77370ffa08c4421
parent0fccdd1e356bf0283359d3d3f52b0532858d43bd (diff)
downloadkvmtool-aarch64/vcpu-pinning.tar.gz
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
-rw-r--r--arm/aarch64/include/kvm/kvm-config-arch.h4
-rw-r--r--arm/aarch64/kvm-cpu.c38
-rw-r--r--arm/include/arm-common/kvm-config-arch.h1
3 files changed, 42 insertions, 1 deletions
diff --git a/arm/aarch64/include/kvm/kvm-config-arch.h b/arm/aarch64/include/kvm/kvm-config-arch.h
index 1c40bbac..74fc0fc7 100644
--- a/arm/aarch64/include/kvm/kvm-config-arch.h
+++ b/arm/aarch64/include/kvm/kvm-config-arch.h
@@ -15,6 +15,10 @@ int vcpu_affinity_parser(const struct option *opt, const char *arg, int unset);
OPT_CALLBACK('\0', "vcpu-affinity", kvm, "cpulist", \
"Specify the CPU affinity that will apply to " \
"all VCPUs", vcpu_affinity_parser, kvm), \
+ OPT_BOOLEAN('\0', "vcpu-pinned", &(cfg)->vcpu_pinned, \
+ "1:1 pin vCPUs to CPUs in the vcpu-affinity" \
+ "list. You must specify at least as many CPUs" \
+ "as vCPUs in the vcpu-affinity list."), \
OPT_U64('\0', "kaslr-seed", &(cfg)->kaslr_seed, \
"Specify random seed for Kernel Address Space " \
"Layout Randomization (KASLR)"), \
diff --git a/arm/aarch64/kvm-cpu.c b/arm/aarch64/kvm-cpu.c
index 316e20c7..fd978331 100644
--- a/arm/aarch64/kvm-cpu.c
+++ b/arm/aarch64/kvm-cpu.c
@@ -153,17 +153,53 @@ int kvm_cpu__configure_features(struct kvm_cpu *vcpu)
return 0;
}
+static cpu_set_t *kvm_cpu__get_affinity(struct kvm_cpu *vcpu)
+{
+ size_t setsize = CPU_ALLOC_SIZE(NR_CPUS);
+ cpu_set_t *affinity = CPU_ALLOC(NR_CPUS);
+ struct kvm *kvm = vcpu->kvm;
+ unsigned long nr_cpus;
+ int i;
+
+ if (!kvm->arch.vcpu_affinity_cpuset || !affinity)
+ return NULL;
+
+ CPU_ZERO_S(CPU_ALLOC_SIZE(NR_CPUS), affinity);
+
+ if (!kvm->cfg.arch.vcpu_pinned) {
+ CPU_OR_S(setsize, affinity, affinity, kvm->arch.vcpu_affinity_cpuset);
+ return affinity;
+ }
+
+ for (i = 0, nr_cpus = 0; i < NR_CPUS; i++) {
+ if (!CPU_ISSET_S(i, setsize, kvm->arch.vcpu_affinity_cpuset))
+ continue;
+
+ if (nr_cpus == vcpu->cpu_id) {
+ CPU_SET_S(i, setsize, affinity);
+ return affinity;
+ }
+
+ nr_cpus++;
+ }
+
+ die("Invalid vcpu-affinity mask for vcpu pinning");
+ return NULL;
+}
+
void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu)
{
struct kvm *kvm = vcpu->kvm;
cpu_set_t *affinity;
int ret;
- affinity = kvm->arch.vcpu_affinity_cpuset;
+ affinity = kvm_cpu__get_affinity(vcpu);
if (affinity) {
ret = sched_setaffinity(0, sizeof(cpu_set_t), affinity);
if (ret == -1)
die_perror("sched_setaffinity");
+
+ CPU_FREE(affinity);
}
if (kvm->cfg.arch.aarch32_guest)
diff --git a/arm/include/arm-common/kvm-config-arch.h b/arm/include/arm-common/kvm-config-arch.h
index 223b5a93..b35eeeb6 100644
--- a/arm/include/arm-common/kvm-config-arch.h
+++ b/arm/include/arm-common/kvm-config-arch.h
@@ -15,6 +15,7 @@ struct kvm_config_arch {
u64 fw_addr;
bool no_pvtime;
bool in_kernel_smccc;
+ bool vcpu_pinned;
};
int irqchip_parser(const struct option *opt, const char *arg, int unset);