Re: [Xen-devel] [PATCH 2/2] xen: add update indicator to vcpu_runstate_info
On Fri, 20 May 2016, Jan Beulich wrote: > >>> On 20.05.16 at 17:54,wrote: > > On 20/05/16 17:36, Jan Beulich wrote: > > On 20.05.16 at 17:04, wrote: > >>> On 20/05/16 16:49, Jan Beulich wrote: > >>> On 20.05.16 at 15:22, wrote: > > if ( guest_handle_is_null(runstate_guest(v)) ) > > return 1; > > > > +update_flag = VM_ASSIST(v->domain, runstate_update_flag); > > + > > smap_policy = smap_policy_change(v, SMAP_CHECK_ENABLED); > > > > +if ( update_flag ) > > +{ > > +off = offsetof(struct vcpu_runstate_info, state_entry_time) + > > 7; > > How come this is outside the following if()? Also sizeof(...) - 1 please > instead of the literal 7. > >>> > >>> I'm using off for the source address in __raw_copy_to_guest(), too. > >> > >> But the offset should, afaict, be different for 32-bit (x86) and > >> 64-bit (or ARM). > > > > Why? The offset is applied to v->runstate which clearly is the same > > for 32 and 64 bit domains, as it is the hypervisor private structure. > > Different offsets have to be applied at the destination side only, and > > this is done properly (at least I think so). > > But as you say you use the offset for two purposes: The use on > the guest handle is which is problematic; the use on the hypervisor > internal structure is of course fine. The code is a bit ugly, but it looks like it would work on ARM ___ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH 2/2] xen: add update indicator to vcpu_runstate_info
>>> On 20.05.16 at 17:54,wrote: > On 20/05/16 17:36, Jan Beulich wrote: > On 20.05.16 at 17:04, wrote: >>> On 20/05/16 16:49, Jan Beulich wrote: >>> On 20.05.16 at 15:22, wrote: > if ( guest_handle_is_null(runstate_guest(v)) ) > return 1; > > +update_flag = VM_ASSIST(v->domain, runstate_update_flag); > + > smap_policy = smap_policy_change(v, SMAP_CHECK_ENABLED); > > +if ( update_flag ) > +{ > +off = offsetof(struct vcpu_runstate_info, state_entry_time) + 7; How come this is outside the following if()? Also sizeof(...) - 1 please instead of the literal 7. >>> >>> I'm using off for the source address in __raw_copy_to_guest(), too. >> >> But the offset should, afaict, be different for 32-bit (x86) and >> 64-bit (or ARM). > > Why? The offset is applied to v->runstate which clearly is the same > for 32 and 64 bit domains, as it is the hypervisor private structure. > Different offsets have to be applied at the destination side only, and > this is done properly (at least I think so). But as you say you use the offset for two purposes: The use on the guest handle is which is problematic; the use on the hypervisor internal structure is of course fine. Jan ___ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH 2/2] xen: add update indicator to vcpu_runstate_info
On 20/05/16 17:36, Jan Beulich wrote: On 20.05.16 at 17:04,wrote: >> On 20/05/16 16:49, Jan Beulich wrote: >> On 20.05.16 at 15:22, wrote: if ( guest_handle_is_null(runstate_guest(v)) ) return 1; +update_flag = VM_ASSIST(v->domain, runstate_update_flag); + smap_policy = smap_policy_change(v, SMAP_CHECK_ENABLED); +if ( update_flag ) +{ +off = offsetof(struct vcpu_runstate_info, state_entry_time) + 7; >>> >>> How come this is outside the following if()? Also sizeof(...) - 1 please >>> instead of the literal 7. >> >> I'm using off for the source address in __raw_copy_to_guest(), too. > > But the offset should, afaict, be different for 32-bit (x86) and > 64-bit (or ARM). Why? The offset is applied to v->runstate which clearly is the same for 32 and 64 bit domains, as it is the hypervisor private structure. Different offsets have to be applied at the destination side only, and this is done properly (at least I think so). Juergen ___ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH 2/2] xen: add update indicator to vcpu_runstate_info
>>> On 20.05.16 at 17:04,wrote: > On 20/05/16 16:49, Jan Beulich wrote: > On 20.05.16 at 15:22, wrote: >>> if ( guest_handle_is_null(runstate_guest(v)) ) >>> return 1; >>> >>> +update_flag = VM_ASSIST(v->domain, runstate_update_flag); >>> + >>> smap_policy = smap_policy_change(v, SMAP_CHECK_ENABLED); >>> >>> +if ( update_flag ) >>> +{ >>> +off = offsetof(struct vcpu_runstate_info, state_entry_time) + 7; >> >> How come this is outside the following if()? Also sizeof(...) - 1 please >> instead of the literal 7. > > I'm using off for the source address in __raw_copy_to_guest(), too. But the offset should, afaict, be different for 32-bit (x86) and 64-bit (or ARM). Jan ___ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH 2/2] xen: add update indicator to vcpu_runstate_info
On 20/05/16 16:49, Jan Beulich wrote: On 20.05.16 at 15:22,wrote: >> --- a/xen/arch/x86/domain.c >> +++ b/xen/arch/x86/domain.c >> @@ -1925,13 +1925,37 @@ static void paravirt_ctxt_switch_to(struct vcpu *v) >> bool_t update_runstate_area(struct vcpu *v) >> { >> bool_t rc; >> +bool_t update_flag; > > I think this variable is superfluous (and causes more register pressure > in the compiler), since ... > >> smap_check_policy_t smap_policy; >> +void __user *guest_handle = NULL; > > ... you can key off of this being non-NULL or ... > >> +unsigned off = 0; > > ... this being non-zero in the second if(). Okay. Will change. > >> if ( guest_handle_is_null(runstate_guest(v)) ) >> return 1; >> >> +update_flag = VM_ASSIST(v->domain, runstate_update_flag); >> + >> smap_policy = smap_policy_change(v, SMAP_CHECK_ENABLED); >> >> +if ( update_flag ) >> +{ >> +off = offsetof(struct vcpu_runstate_info, state_entry_time) + 7; > > How come this is outside the following if()? Also sizeof(...) - 1 please > instead of the literal 7. I'm using off for the source address in __raw_copy_to_guest(), too. Regarding sizeof(): okay. > >> --- a/xen/include/public/vcpu.h >> +++ b/xen/include/public/vcpu.h >> @@ -84,6 +84,12 @@ struct vcpu_runstate_info { >> /* When was current state entered (system time, ns)? */ >> uint64_t state_entry_time; >> /* >> + * Update indicator set in state_entry_time: >> + * When activated via VMASST_TYPE_runstate_update_flag, set during >> + * updates in guest memory mapped copy of vcpu_runstate_info. >> + */ >> +#define XEN_RUNSTATE_UPDATE (1ULL << 63) > > I think this should be UINT64_C(1), as ULL is not a C89 compatible > suffix, but by requiring uint64_t I think we can imply that along with > that C99 type the platform also surfaces respective macros. Okay. Juergen ___ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH 2/2] xen: add update indicator to vcpu_runstate_info
>>> On 20.05.16 at 15:22,wrote: > --- a/xen/arch/x86/domain.c > +++ b/xen/arch/x86/domain.c > @@ -1925,13 +1925,37 @@ static void paravirt_ctxt_switch_to(struct vcpu *v) > bool_t update_runstate_area(struct vcpu *v) > { > bool_t rc; > +bool_t update_flag; I think this variable is superfluous (and causes more register pressure in the compiler), since ... > smap_check_policy_t smap_policy; > +void __user *guest_handle = NULL; ... you can key off of this being non-NULL or ... > +unsigned off = 0; ... this being non-zero in the second if(). > if ( guest_handle_is_null(runstate_guest(v)) ) > return 1; > > +update_flag = VM_ASSIST(v->domain, runstate_update_flag); > + > smap_policy = smap_policy_change(v, SMAP_CHECK_ENABLED); > > +if ( update_flag ) > +{ > +off = offsetof(struct vcpu_runstate_info, state_entry_time) + 7; How come this is outside the following if()? Also sizeof(...) - 1 please instead of the literal 7. > --- a/xen/include/public/vcpu.h > +++ b/xen/include/public/vcpu.h > @@ -84,6 +84,12 @@ struct vcpu_runstate_info { > /* When was current state entered (system time, ns)? */ > uint64_t state_entry_time; > /* > + * Update indicator set in state_entry_time: > + * When activated via VMASST_TYPE_runstate_update_flag, set during > + * updates in guest memory mapped copy of vcpu_runstate_info. > + */ > +#define XEN_RUNSTATE_UPDATE (1ULL << 63) I think this should be UINT64_C(1), as ULL is not a C89 compatible suffix, but by requiring uint64_t I think we can imply that along with that C99 type the platform also surfaces respective macros. Jan ___ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH 2/2] xen: add update indicator to vcpu_runstate_info
On 20/05/16 14:22, Juergen Gross wrote: > diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c > index 1365b4a..91f256b 100644 > --- a/xen/arch/arm/domain.c > +++ b/xen/arch/arm/domain.c > @@ -239,10 +239,32 @@ static void ctxt_switch_to(struct vcpu *n) > /* Update per-VCPU guest runstate shared memory area (if registered). */ > static void update_runstate_area(struct vcpu *v) > { > +bool_t update_flag; > +void __user *guest_handle = NULL; > +unsigned off = 0; > + > if ( guest_handle_is_null(runstate_guest(v)) ) > return; > > +update_flag = VM_ASSIST(v->domain, runstate_update_flag); > +if ( update_flag ) > +{ > +off = offsetof(struct vcpu_runstate_info, state_entry_time) + 7; > +guest_handle = v->runstate_guest.p; > +guest_handle += off; > +v->runstate.state_entry_time |= XEN_RUNSTATE_UPDATE; > +__raw_copy_to_guest(guest_handle, (void *)>runstate + off, 1); > +wmb(); smp_wmb(), throughout. A whole lot of code gets this wrong in Xen, and plan to clean it all up in 4.8 ~Andrew ___ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
Re: [Xen-devel] [PATCH 2/2] xen: add update indicator to vcpu_runstate_info
On 20/05/16 15:34, Andrew Cooper wrote: > On 20/05/16 14:22, Juergen Gross wrote: >> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c >> index 1365b4a..91f256b 100644 >> --- a/xen/arch/arm/domain.c >> +++ b/xen/arch/arm/domain.c >> @@ -239,10 +239,32 @@ static void ctxt_switch_to(struct vcpu *n) >> /* Update per-VCPU guest runstate shared memory area (if registered). */ >> static void update_runstate_area(struct vcpu *v) >> { >> +bool_t update_flag; >> +void __user *guest_handle = NULL; >> +unsigned off = 0; >> + >> if ( guest_handle_is_null(runstate_guest(v)) ) >> return; >> >> +update_flag = VM_ASSIST(v->domain, runstate_update_flag); >> +if ( update_flag ) >> +{ >> +off = offsetof(struct vcpu_runstate_info, state_entry_time) + 7; >> +guest_handle = v->runstate_guest.p; >> +guest_handle += off; >> +v->runstate.state_entry_time |= XEN_RUNSTATE_UPDATE; >> +__raw_copy_to_guest(guest_handle, (void *)>runstate + off, 1); >> +wmb(); > > smp_wmb(), throughout. Okay. Juergen ___ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel
[Xen-devel] [PATCH 2/2] xen: add update indicator to vcpu_runstate_info
In order to support reading another vcpu's mapped vcpu_runstate_info an indicator for an occurring update of the runstate information is needed. Add the possibility to activate setting this indicator in the highest bit of state_entry_time via a vm_assist hypercall. When activated the update indicator will be set before the runstate information is modified in guest memory and it will be reset after modification is done. As state_entry_time is guaranteed to be different after each update the guest can detect any update (either in progress or while reading the runstate data) by comparing state_entry_time before and after reading runstate data: in case the values differ or the update indicator was set the data might be inconsistent and should be reread. Signed-off-by: Juergen Gross--- xen/arch/arm/domain.c| 22 ++ xen/arch/x86/domain.c| 31 +++ xen/include/asm-arm/config.h | 2 +- xen/include/asm-x86/config.h | 1 + xen/include/public/vcpu.h| 6 ++ xen/include/public/xen.h | 7 +++ 6 files changed, 68 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 1365b4a..91f256b 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -239,10 +239,32 @@ static void ctxt_switch_to(struct vcpu *n) /* Update per-VCPU guest runstate shared memory area (if registered). */ static void update_runstate_area(struct vcpu *v) { +bool_t update_flag; +void __user *guest_handle = NULL; +unsigned off = 0; + if ( guest_handle_is_null(runstate_guest(v)) ) return; +update_flag = VM_ASSIST(v->domain, runstate_update_flag); +if ( update_flag ) +{ +off = offsetof(struct vcpu_runstate_info, state_entry_time) + 7; +guest_handle = v->runstate_guest.p; +guest_handle += off; +v->runstate.state_entry_time |= XEN_RUNSTATE_UPDATE; +__raw_copy_to_guest(guest_handle, (void *)>runstate + off, 1); +wmb(); +} + __copy_to_guest(runstate_guest(v), >runstate, 1); + +if ( update_flag ) +{ +v->runstate.state_entry_time &= ~XEN_RUNSTATE_UPDATE; +wmb(); +__raw_copy_to_guest(guest_handle, (void *)>runstate + off, 1); +} } static void schedule_tail(struct vcpu *prev) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 5af2cc5..dfaee5d 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1925,13 +1925,37 @@ static void paravirt_ctxt_switch_to(struct vcpu *v) bool_t update_runstate_area(struct vcpu *v) { bool_t rc; +bool_t update_flag; smap_check_policy_t smap_policy; +void __user *guest_handle = NULL; +unsigned off = 0; if ( guest_handle_is_null(runstate_guest(v)) ) return 1; +update_flag = VM_ASSIST(v->domain, runstate_update_flag); + smap_policy = smap_policy_change(v, SMAP_CHECK_ENABLED); +if ( update_flag ) +{ +off = offsetof(struct vcpu_runstate_info, state_entry_time) + 7; +if ( has_32bit_shinfo(v->domain) ) +{ +guest_handle = v->runstate_guest.compat.p; +guest_handle += offsetof(struct compat_vcpu_runstate_info, + state_entry_time) + 7; +} +else +{ +guest_handle = v->runstate_guest.native.p; +guest_handle += off; +} +v->runstate.state_entry_time |= XEN_RUNSTATE_UPDATE; +__raw_copy_to_guest(guest_handle, (void *)>runstate + off, 1); +wmb(); +} + if ( has_32bit_shinfo(v->domain) ) { struct compat_vcpu_runstate_info info; @@ -1944,6 +1968,13 @@ bool_t update_runstate_area(struct vcpu *v) rc = __copy_to_guest(runstate_guest(v), >runstate, 1) != sizeof(v->runstate); +if ( update_flag ) +{ +v->runstate.state_entry_time &= ~XEN_RUNSTATE_UPDATE; +wmb(); +__raw_copy_to_guest(guest_handle, (void *)>runstate + off, 1); +} + smap_policy_change(v, smap_policy); return rc; diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h index 563f49b..ce3edc2 100644 --- a/xen/include/asm-arm/config.h +++ b/xen/include/asm-arm/config.h @@ -199,7 +199,7 @@ extern unsigned long frametable_virt_end; #define watchdog_disable() ((void)0) #define watchdog_enable() ((void)0) -#define VM_ASSIST_VALID (0) +#define VM_ASSIST_VALID (1UL << VMASST_TYPE_runstate_update_flag) #endif /* __ARM_CONFIG_H__ */ /* diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index c10129d..6fd84e7 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -332,6 +332,7 @@ extern unsigned long xen_phys_start; (1UL << VMASST_TYPE_writable_pagetables) | \ (1UL << VMASST_TYPE_pae_extended_cr3)| \