On 16/01/2023 21:57, David Woodhouse wrote:
From: David Woodhouse <d...@amazon.co.uk>

The kvm_xen_inject_vcpu_callback_vector() function will either deliver
the per-vCPU local APIC vector (as an MSI), or just kick the vCPU out
of the kernel to trigger KVM's automatic delivery of the global vector.
Support for asserting the GSI/PCI_INTX callbacks will come later.

Also add kvm_xen_get_vcpu_info_hva() which returns the vcpu_info of
a given vCPU.

Signed-off-by: David Woodhouse <d...@amazon.co.uk>
---
  include/sysemu/kvm_xen.h  |  2 +
  target/i386/cpu.h         |  2 +
  target/i386/kvm/xen-emu.c | 86 ++++++++++++++++++++++++++++++++++++---
  3 files changed, 84 insertions(+), 6 deletions(-)

diff --git a/include/sysemu/kvm_xen.h b/include/sysemu/kvm_xen.h
index 3e43cd7843..ee53294deb 100644
--- a/include/sysemu/kvm_xen.h
+++ b/include/sysemu/kvm_xen.h
@@ -17,6 +17,8 @@
  #define INVALID_GFN UINT64_MAX
uint32_t kvm_xen_get_caps(void);
+void *kvm_xen_get_vcpu_info_hva(uint32_t vcpu_id);
+void kvm_xen_inject_vcpu_callback_vector(uint32_t vcpu_id, int type);
#define kvm_xen_has_cap(cap) (!!(kvm_xen_get_caps() & \
                                   KVM_XEN_HVM_CONFIG_ ## cap))
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 938a1b9c8b..c9b12e7476 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1788,6 +1788,8 @@ typedef struct CPUArchState {
  #endif
  #if defined(CONFIG_KVM)
      struct kvm_nested_state *nested_state;
+    MemoryRegion *xen_vcpu_info_mr;
+    void *xen_vcpu_info_hva;
      uint64_t xen_vcpu_info_gpa;
      uint64_t xen_vcpu_info_default_gpa;
      uint64_t xen_vcpu_time_info_gpa;
diff --git a/target/i386/kvm/xen-emu.c b/target/i386/kvm/xen-emu.c
index b0e7620b16..d04d858912 100644
--- a/target/i386/kvm/xen-emu.c
+++ b/target/i386/kvm/xen-emu.c
@@ -20,6 +20,8 @@
  #include "trace.h"
  #include "sysemu/runstate.h"
+#include "hw/pci/msi.h"
+#include "hw/i386/apic-msidef.h"
  #include "hw/i386/kvm/xen_overlay.h"
  #include "hw/i386/kvm/xen_evtchn.h"
@@ -247,6 +249,35 @@ static void do_set_vcpu_callback_vector(CPUState *cs, run_on_cpu_data data)
      }
  }
+static int set_vcpu_info(CPUState *cs, uint64_t gpa)
+{
+    X86CPU *cpu = X86_CPU(cs);
+    CPUX86State *env = &cpu->env;
+    MemoryRegionSection mrs;
+    int ret;
+
+    ret = kvm_xen_set_vcpu_attr(cs, KVM_XEN_VCPU_ATTR_TYPE_VCPU_INFO, gpa);
+    if (ret || gpa == INVALID_GPA) {
+    fail:

Ick. Do we really want cross-block gotos? For me it would look a lot nicer if you did a forward jump here and later and put the label+code after the `return 0`.

+        if (env->xen_vcpu_info_mr) {
+            memory_region_unref(env->xen_vcpu_info_mr);
+            env->xen_vcpu_info_mr = NULL;
+        }
+        env->xen_vcpu_info_hva = NULL;
+        return ret;
+    }
+
+    mrs = memory_region_find(get_system_memory(), gpa, sizeof(struct 
vcpu_info));
+    if (!mrs.mr || !mrs.mr->ram_block || mrs.size < sizeof(struct vcpu_info) ||
+        !(env->xen_vcpu_info_hva = qemu_map_ram_ptr(mrs.mr->ram_block,
+                                                    
mrs.offset_within_region))) {
+        ret = -EINVAL;
+        goto fail;
+    }
+    env->xen_vcpu_info_mr = mrs.mr;
+    return 0;
+}


Reply via email to