From: Jan Beulich <jbeul...@suse.com> Before adding a new vCPU operation to register the secondary time area by guest-physical address, add code to actually keep such areas up-to- date.
Note that pages aren't marked dirty when written to (matching the handling of space mapped by map_vcpu_info()), on the basis that the registrations are lost anyway across migration (or would need re- populating at the target for transparent migration). Plus the contents of the areas in question have to be deemed volatile in the first place (so saving a "most recent" value is pretty meaningless even for e.g. snapshotting). Signed-off-by: Jan Beulich <jbeul...@suse.com> Reviewed-by: Roger Pau Monné <roger....@citrix.com> --- xen/arch/x86/time.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index af40a9993c81..332d2d79aeae 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -1566,12 +1566,34 @@ static void __update_vcpu_system_time(struct vcpu *v, int force) v->arch.pv.pending_system_time = _u; } +static void write_time_guest_area(struct vcpu_time_info *map, + const struct vcpu_time_info *src) +{ + /* 1. Update userspace version. */ + write_atomic(&map->version, src->version); + smp_wmb(); + + /* 2. Update all other userspace fields. */ + *map = *src; + + /* 3. Update userspace version again. */ + smp_wmb(); + write_atomic(&map->version, version_update_end(src->version)); +} + bool update_secondary_system_time(struct vcpu *v, struct vcpu_time_info *u) { XEN_GUEST_HANDLE(vcpu_time_info_t) user_u = v->arch.time_info_guest; + struct vcpu_time_info *map = v->arch.time_guest_area.map; struct guest_memory_policy policy = { .nested_guest_mode = false }; + if ( map ) + { + write_time_guest_area(map, u); + return true; + } + if ( guest_handle_is_null(user_u) ) return true; -- 2.42.0