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@ts.fujitsu.com
Mies-van-der-Rohe-Str. 8 Internet: ts.fujitsu.com
D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html
>>> On 13.11.13 at 14:50, Juergen Gross <juergen.gross@ts.fujitsu.com> wrote: > 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).__update_vcpu_system_time() specifically considers the case of vTSC, so I''m not really clear what your problem here is. NOW() (and hence state_entry_time) are in ns units, and the information presented in struct vcpu_time_info should be sufficient to do the necessary mapping (or else I can''t see what''s different in your case from the usual PV or PVHVM one).> 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.No, that one''s defined to be matching up with vcpu_time_info''s system_time. Jan
On 20.11.2013 14:07, Jan Beulich wrote:>>>> On 13.11.13 at 14:50, Juergen Gross <juergen.gross@ts.fujitsu.com> wrote: >> 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). > > __update_vcpu_system_time() specifically considers the case of > vTSC, so I''m not really clear what your problem here is. NOW() > (and hence state_entry_time) are in ns units, and the information > presented in struct vcpu_time_info should be sufficient to do the > necessary mapping (or else I can''t see what''s different in your > case from the usual PV or PVHVM one). > >> 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. > > No, that one''s defined to be matching up with vcpu_time_info''s > system_time.Ah, okay. Then this was a mis-interpretation on my side. Thanks for the info. :-) I''ll start another try based on this. Juergen -- Juergen Gross Principal Developer Operating Systems PBG PDG ES&S SWE OS6 Telephone: +49 (0) 89 62060 2932 Fujitsu e-mail: juergen.gross@ts.fujitsu.com Mies-van-der-Rohe-Str. 8 Internet: ts.fujitsu.com D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html