---
 accel/kvm/kvm-accel-ops.c | 43 +++++++++++++++++++++++++++++++++++++++
 hw/arm/virt.c             | 25 +++++++++++++++++++++++
 include/hw/arm/virt.h     |  1 +
 3 files changed, 69 insertions(+)

diff --git a/accel/kvm/kvm-accel-ops.c b/accel/kvm/kvm-accel-ops.c
index 54f19028..3f8f1a3a 100644
--- a/accel/kvm/kvm-accel-ops.c
+++ b/accel/kvm/kvm-accel-ops.c
@@ -26,6 +26,47 @@
 #include <linux/kvm.h>
 #include "kvm-cpus.h"
 
+extern bool enable_kata_affinity;
+
+void BindCpu(unsigned int n);
+unsigned int get_cpuset_cpu_id(unsigned int thread_id, cpu_set_t *set);
+void bind_cpu_thread(unsigned long vcpu_id);
+
+void BindCpu(unsigned int n)
+{
+    cpu_set_t cpuSet;
+    CPU_ZERO(&cpuSet);
+    CPU_SET(n, &cpuSet);
+    pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuSet);
+}
+
+unsigned int get_cpuset_cpu_id(unsigned int thread_id, cpu_set_t *set)
+{
+    unsigned int i, find_num;
+
+    find_num = 0;
+    for (i = 0; i < 256; i++) {
+        if(CPU_ISSET(i, set)) {
+            find_num++;
+            if (find_num == thread_id + 1)
+                return i;
+            }
+	}
+    return i;
+}
+
+void bind_cpu_thread(unsigned long vcpu_id)
+{
+    unsigned int cpu_id;
+    pid_t pid = getpid();
+    cpu_set_t p_cpuSet;
+
+    sched_getaffinity(pid, sizeof(cpu_set_t), &p_cpuSet);
+    cpu_id = get_cpuset_cpu_id(vcpu_id, &p_cpuSet);
+    if (cpu_id < 256)
+        BindCpu(cpu_id);
+}
+
 static void *kvm_vcpu_thread_fn(void *arg)
 {
     CPUState *cpu = arg;
@@ -39,6 +80,8 @@ static void *kvm_vcpu_thread_fn(void *arg)
     cpu->neg.can_do_io = true;
     current_cpu = cpu;
 
+    if (enable_kata_affinity)
+        bind_cpu_thread(kvm_arch_vcpu_id(cpu));
     r = kvm_init_vcpu(cpu, &error_fatal);
     kvm_init_cpu_signals(cpu);
 
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b69f7e93..b6858579 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -233,6 +233,8 @@ static const char *valid_cpus[] = {
     ARM_CPU_TYPE_NAME("max"),
 };
 
+bool enable_kata_affinity = false;
+
 static CPUArchId *virt_find_cpu_slot(MachineState *ms, int vcpuid);
 static int virt_get_socket_id(const MachineState *ms, int cpu_index);
 static int virt_get_cluster_id(const MachineState *ms, int cpu_index);
@@ -2572,6 +2574,13 @@ static void machvirt_init(MachineState *machine)
                                                 tag_sysmem, -1);
         }
     }
+    if (object_property_find(OBJECT(current_machine), "kata-affinity")) {
+        g_autofree char *kata_affinity = object_property_get_str(OBJECT(current_machine),
+                                                                "kata-affinity", &error_abort);
+        if (!strcmp(kata_affinity, "on")) {
+            enable_kata_affinity = true;
+        }
+    }
 
     create_fdt(vms);
 
@@ -3893,6 +3902,19 @@ static void virt_set_kvm_type(Object *obj, const char *value, Error **errp G_GNU
     vms->kvm_type = g_strdup(value);
 }
 
+static char *virt_get_kata_affinity(Object *obj, Error **errp G_GNUC_UNUSED)
+{
+    VirtMachineState *vms = VIRT_MACHINE(obj);
+    return g_strdup(vms->kata_affinity);
+}
+
+static void virt_set_kata_affinity(Object *obj, const char *value, Error **errp G_GNUC_UNUSED)
+{
+    VirtMachineState *vms = VIRT_MACHINE(obj);
+    g_free(vms->kata_affinity);
+    vms->kata_affinity = g_strdup(value);
+}
+
 static void virt_instance_init(Object *obj)
 {
     VirtMachineState *vms = VIRT_MACHINE(obj);
@@ -3956,6 +3978,9 @@ static void virt_instance_init(Object *obj)
 
     object_property_add_str(obj, "kvm-type", virt_get_kvm_type, virt_set_kvm_type);
     object_property_set_description(obj, "kvm-type", "CVM or Normal VM");
+
+    object_property_add_str(obj, "kata-affinity", virt_get_kata_affinity, virt_set_kata_affinity);
+    object_property_set_description(obj, "kata-affinity", "enable kata affinity or not");
 }
 
 static const TypeInfo virt_machine_info = {
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 76a0d3fa..11b5d40b 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -184,6 +184,7 @@ struct VirtMachineState {
     char *oem_id;
     char *oem_table_id;
     char *kvm_type;
+    char *kata_affinity;
     NotifierList cpuhp_notifiers;
 };
 
-- 
2.33.0