[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] using mapped vcpu_runstate_info in hvm guest
Hi, I'm trying to obtain runstate information from the hypervisor in a hvm guest via VCPUOP_register_runstate_memory_area. This works, but the information is not completely suitable for a hvm guest: I can see the time summed up in the different states, but I'm not able to deduce the exact time the current vcpu has been running. I see the time when the last change to the running state happened (state_entry_time), but this time is the hypervisor system time obtained via NOW(). I can't see how to map this information to any time information available to the guest (e.g. the tsc value). A solution would be to modify the runstate information mapped via VCPUOP_register_runstate_memory_area: it could contain state_entry_time rebased to the guests tsc. I tried to patch the hypervisor accordingly, but failed to find the correct time offset. The following patch returned a value for state_entry_time about 60 seconds in the past: diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index b67fcb8..c89bbaf 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1292,19 +1292,32 @@ static void paravirt_ctxt_switch_to(struct vcpu *v) /* Update per-VCPU guest runstate shared memory area (if registered). */ static void update_runstate_area(struct vcpu *v) { + struct vcpu_runstate_info info_local; + if ( guest_handle_is_null(runstate_guest(v)) ) return; + info_local = v->runstate; + if ( is_hvm_vcpu(v) ) + { + if ( v->arch.hvm_vcpu.cache_tsc_offset < 0 ) + info_local.state_entry_time -= + tsc_ticks2ns(-v->arch.hvm_vcpu.cache_tsc_offset); + else + info_local.state_entry_time += + tsc_ticks2ns(v->arch.hvm_vcpu.cache_tsc_offset); + } + if ( has_32bit_shinfo(v->domain) ) { struct compat_vcpu_runstate_info info; - XLAT_vcpu_runstate_info(&info, &v->runstate); + XLAT_vcpu_runstate_info(&info, &info_local); __copy_to_guest(v->runstate_guest.compat, &info, 1); return; } - __copy_to_guest(runstate_guest(v), &v->runstate, 1); + __copy_to_guest(runstate_guest(v), &info_local, 1); } static inline int need_full_gdt(struct vcpu *v) What am I missing? Is there any additional offset to take into account? Another problem is the consistency of the mapped data: I can use the data of the current vcpu by doing a local copy and a binary compare afterwards. Only in case of a match I can be sure no update has happened between interpreting different members of the copied structure. It is not possible, however, to verify the consistency of the runstate of a foreign vcpu. The __copy_to_guest() in update_runstate_area() could have been interrupted (e.g. by a NMI) without any chance to detect this on another physical cpu currently examining the data. The only way to avoid this would be a version count (like in vcpu_time_info) which is updated before and after modifying the runstate data. Any thoughts? Juergen -- Juergen Gross Principal Developer Operating Systems PBG PDG ES&S SWE OS6 Telephone: +49 (0) 89 62060 2932 Fujitsu e-mail: juergen.gross@xxxxxxxxxxxxxx Mies-van-der-Rohe-Str. 8 Internet: ts.fujitsu.com D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |