]> www.infradead.org Git - users/dwmw2/qemu.git/commitdiff
i386/xen: handle register_vcpu_time_memory_area
authorJoao Martins <joao.m.martins@oracle.com>
Mon, 23 Jul 2018 15:24:36 +0000 (11:24 -0400)
committerJoao Martins <joao.m.martins@oracle.com>
Tue, 19 Feb 2019 14:00:57 +0000 (09:00 -0500)
In order to support Linux vdso in Xen.

Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
linux-headers/linux/kvm.h
target/i386/xen.c

index c6e9d97be8379618a19eabbc8f014217b0972df6..496e1a77aae1e92ab358006fb9677b829b11caeb 100644 (file)
@@ -1473,6 +1473,7 @@ struct kvm_xen_hvm_attr {
 
 #define KVM_XEN_ATTR_TYPE_SHARED_INFO       0x0
 #define KVM_XEN_ATTR_TYPE_VCPU_INFO         0x1
+#define KVM_XEN_ATTR_TYPE_VCPU_TIME_INFO    0x2
 
 /* Secure Encrypted Virtualization command */
 enum sev_cmd_id {
index eeafe6c9b3e69546764db54fcf2fbdf14a491584..92a41345175a16b2e5ebfb7a49a47b69e6870063 100644 (file)
@@ -45,17 +45,22 @@ static void *gpa_to_hva(uint64_t gpa)
                                              mrs.offset_within_region);
 }
 
-static void *gva_to_hva(CPUState *cs, uint64_t gva)
+static uint64_t gva_to_gpa(CPUState *cs, uint64_t gva)
 {
     struct kvm_translation t = { .linear_address = gva };
     int err;
 
     err = kvm_vcpu_ioctl(cs, KVM_TRANSLATE, &t);
     if (err || !t.valid) {
-        return NULL;
+        return 0;
     }
 
-    return gpa_to_hva(t.physical_address);
+    return t.physical_address;
+}
+
+static void *gva_to_hva(CPUState *cs, uint64_t gva)
+{
+    return gpa_to_hva(gva_to_gpa(cs, gva));
 }
 
 static void arch_init_hypercall_page(CPUState *cs, void *addr)
@@ -260,6 +265,27 @@ static int vcpuop_register_vcpu_info(CPUState *cs, CPUState *target,
     return xen_set_vcpu_attr(target, KVM_XEN_ATTR_TYPE_VCPU_INFO, gpa);
 }
 
+static int vcpuop_register_vcpu_time_info(CPUState *cs, CPUState *target,
+                                          uint64_t arg)
+{
+    struct vcpu_register_time_memory_area *tma;
+    uint64_t gpa;
+    void *hva;
+
+    tma = gva_to_hva(cs, arg);
+    if (!tma) {
+        return -EFAULT;
+    }
+
+    hva = gva_to_hva(cs, tma->addr.p);
+    if (!hva || !tma->addr.p) {
+        return -EFAULT;
+    }
+
+    gpa = gva_to_gpa(cs, tma->addr.p);
+    return xen_set_vcpu_attr(target, KVM_XEN_ATTR_TYPE_VCPU_TIME_INFO, gpa);
+}
+
 static int kvm_xen_hcall_vcpu_op(struct kvm_xen_exit *exit, X86CPU *cpu,
                                  int cmd, int vcpu_id, uint64_t arg)
 {
@@ -268,6 +294,10 @@ static int kvm_xen_hcall_vcpu_op(struct kvm_xen_exit *exit, X86CPU *cpu,
     int err = -ENOSYS;
 
     switch (cmd) {
+    case VCPUOP_register_vcpu_time_memory_area: {
+            err = vcpuop_register_vcpu_time_info(cs, dest, arg);
+            break;
+        }
     case VCPUOP_register_vcpu_info: {
             err = vcpuop_register_vcpu_info(cs, dest, arg);
             break;