From: Joao Martins Date: Mon, 23 Jul 2018 15:24:36 +0000 (-0400) Subject: i386/xen: handle register_vcpu_time_memory_area X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=afc2042fc15670103f624294e391ad7f09a6a4a1;p=users%2Fdwmw2%2Fqemu.git i386/xen: handle register_vcpu_time_memory_area In order to support Linux vdso in Xen. Signed-off-by: Joao Martins --- diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h index c6e9d97be8..496e1a77aa 100644 --- a/linux-headers/linux/kvm.h +++ b/linux-headers/linux/kvm.h @@ -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 { diff --git a/target/i386/xen.c b/target/i386/xen.c index eeafe6c9b3..92a4134517 100644 --- a/target/i386/xen.c +++ b/target/i386/xen.c @@ -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;