| 
         
xen-devel
[Xen-devel] Re: [patch] ACM ops interface
 
 hollisb@xxxxxxxxxxxxxxxxxxxxxxx wrote on 06/08/2006
11:01:17 AM: 
 
> [Resend due to xense-devel list borkage.] 
>  
> Hi, I noticed a few small issues in the ACM code. 
 Thanks for looking into them!!
  
> First, it isn't using XEN_GUEST_HANDLEs where it should (i.e. when
using 
> pointers in the interface). What's a little scary is that because
it's 
> using void* everywhere, we didn't get any compiler warnings (if you're 
> passing buffers, maybe 'unsigned char *' would be a better type?).
 
 Keir responded to this point already
  
> Second, copy_to/from_user() has been replaced with copy_to/from_guest(), 
> since you can't copy to "userspace" on all architectures.
(To complicate 
> things, there are a couple areas where x86 code actually wants to
copy 
> to a virtual address, but copy_to/from_user() is only valid in 
> arch-specific code.) 
 Seems a sensible thing to do. This part of the patch
makes much sense.
  
> Third, using 'enum' in the interface makes me very nervous. I'm not
a C 
> lawyer, but using an explicitly-sized type would make me a lot happier. 
 We should define constants and a fixed type argument
(e.g. 32bit as you suggest in your patch). You are right that this interface
benefits from clearly defined in its types and sizes.
  
> Finally, a request: It would simplify PowerPC code if the ACM ops
passed 
> around a union that contains every ACM struct, like 'struct dom0_op'. 
> It's a little hard to explain, but if you're curious, have a look
at 
> xenppc_privcmd_dom0_op() in
 
 We just changed away from this for many reasons. It
is at any time pretty clear to which structure the void pointer points.
 See Keir's e-mail.
 
 Thanks
 Reiner
  
> http://xenbits.xensource.com/ext/linux-ppc-2.6.hg?f=aa55dca4028a; 
> file=arch/powerpc/platforms/xen/hcall.c . To support the current ACM 
> ops, we would have to define our own union anyways: 
>     
>    union { 
>       setpolicy; 
>       getpolicy; 
>       ... 
>    } op; 
>     
>    switch (cmd) { 
>       case SETPOLICY: 
>          if (copy_from_user(&op, arg,
sizeof(struct acm_setpolicy))) 
>             return -EFAULT; 
>          break; 
>       case SETPOLICY: 
>          if (copy_from_user(&op, arg,
sizeof(struct acm_setpolicy))) 
>             return -EFAULT; 
>          break; 
>       ... 
>    } 
>     
>    __u32 *version = (__u32 *)&op; 
>    if (*version != ACM_VERSION) 
>       return -EACCES; 
>     
>    switch (cmd) { 
>       case SETPOLICY: 
>          /* munge acm_setpolicy */ 
>       case GETPOLICY: 
>          /* munge acm_getpolicy */ 
>       ... 
>    } 
>  
> If the ACM ops were always passed in a union, we could replace the
first 
> switch with a single copy_from_user(), and also guarantee that 
> "interface_version" is always in the right place (it's only
there 
> coincidentally now). What do you think? 
>  
> Anyways, this compile-tested patch addresses the first three issues
I 
> mentioned. Please add your Signed-off-by and submit upstream if you're 
> happy with it. 
>  
> Thanks! 
>  
> Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx> 
>  
> diff -r 5c726b5ab92b tools/python/xen/lowlevel/acm/acm.c 
> --- a/tools/python/xen/lowlevel/acm/acm.c   Tue Jun 06 15:30:06
2006 -0500 
> +++ b/tools/python/xen/lowlevel/acm/acm.c   Wed Jun 07 12:31:55
2006 -0500 
> @@ -52,7 +52,7 @@ void * __getssid(int domid, uint32_t *bu 
>      } 
>      memset(buf, 0, SSID_BUFFER_SIZE); 
>      getssid.interface_version = ACM_INTERFACE_VERSION; 
> -    getssid.ssidbuf = buf; 
> +    set_xen_guest_handle(getssid.ssidbuf, buf); 
>      getssid.ssidbuf_size = SSID_BUFFER_SIZE; 
>      getssid.get_ssid_by = DOMAINID; 
>      getssid.id.domainid = domid; 
> diff -r 5c726b5ab92b xen/acm/acm_policy.c 
> --- a/xen/acm/acm_policy.c   Tue Jun 06 15:30:06 2006 -0500 
> +++ b/xen/acm/acm_policy.c   Wed Jun 07 12:31:55 2006 -0500 
> @@ -32,7 +32,7 @@ 
>  #include <acm/acm_endian.h> 
>   
>  int 
> -acm_set_policy(void *buf, u32 buf_size, int isuserbuffer) 
> +acm_set_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size, int isuserbuffer) 
>  { 
>      u8 *policy_buffer = NULL; 
>      struct acm_policy_buffer *pol; 
> @@ -45,7 +45,7 @@ acm_set_policy(void *buf, u32 buf_size,  
>          return -ENOMEM; 
>   
>      if (isuserbuffer) { 
> -        if (copy_from_user(policy_buffer, buf,
buf_size)) 
> +        if (copy_from_guest(policy_buffer, buf,
buf_size)) 
>          { 
>              printk("%s: Error
copying!\n",__func__); 
>              goto error_free; 
> @@ -116,7 +116,7 @@ acm_set_policy(void *buf, u32 buf_size,  
>  } 
>   
>  int 
> -acm_get_policy(void *buf, u32 buf_size) 
> +acm_get_policy(XEN_GUEST_HANDLE(void) buf, u32 buf_size) 
>  {  
>      u8 *policy_buffer; 
>      int ret; 
> @@ -162,7 +162,7 @@ acm_get_policy(void *buf, u32 buf_size) 
>          goto error_free_unlock; 
>   
>      bin_pol->len = htonl(ntohl(bin_pol->len)
+ ret); 
> -    if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len))) 
> +    if (copy_to_guest(buf, policy_buffer, ntohl(bin_pol->len))) 
>          goto error_free_unlock; 
>   
>      read_unlock(&acm_bin_pol_rwlock); 
> @@ -177,7 +177,7 @@ acm_get_policy(void *buf, u32 buf_size) 
>  } 
>   
>  int 
> -acm_dump_statistics(void *buf, u16 buf_size) 
> +acm_dump_statistics(XEN_GUEST_HANDLE(void) buf, u16 buf_size) 
>  {  
>      /* send stats to user space */ 
>      u8 *stats_buffer; 
> @@ -208,7 +208,7 @@ acm_dump_statistics(void *buf, u16 buf_s 
>   
>      memcpy(stats_buffer, &acm_stats, sizeof(struct
acm_stats_buffer)); 
>   
> -    if (copy_to_user(buf, stats_buffer, sizeof(struct  
> acm_stats_buffer) + len1 + len2)) 
> +    if (copy_to_guest(buf, stats_buffer, sizeof(struct
 
> acm_stats_buffer) + len1 + len2)) 
>          goto error_lock_free; 
>   
>      read_unlock(&acm_bin_pol_rwlock); 
> @@ -223,7 +223,7 @@ acm_dump_statistics(void *buf, u16 buf_s 
>   
>  
>  int 
> -acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size) 
> +acm_get_ssid(ssidref_t ssidref, XEN_GUEST_HANDLE(void) buf, u16 buf_size) 
>  { 
>      /* send stats to user space */ 
>      u8 *ssid_buffer; 
> @@ -272,7 +272,7 @@ acm_get_ssid(ssidref_t ssidref, u8 *buf, 
>      acm_ssid->len += ret; 
>      acm_ssid->secondary_max_types = ret; 
>   
> -    if (copy_to_user(buf, ssid_buffer, acm_ssid->len)) 
> +    if (copy_to_guest(buf, ssid_buffer, acm_ssid->len)) 
>          goto error_free_unlock; 
>   
>      read_unlock(&acm_bin_pol_rwlock); 
> diff -r 5c726b5ab92b xen/include/public/acm_ops.h 
> --- a/xen/include/public/acm_ops.h   Tue Jun 06 15:30:06 2006
-0500 
> +++ b/xen/include/public/acm_ops.h   Wed Jun 07 12:31:55 2006
-0500 
> @@ -17,7 +17,7 @@ 
>   * This makes sure that old versions of acm tools will stop
working in a 
>   * well-defined way (rather than crashing the machine, for instance). 
>   */ 
> -#define ACM_INTERFACE_VERSION   0xAAAA0007 
> +#define ACM_INTERFACE_VERSION   0xAAAA0008 
>   
>  /************************************************************************/ 
>   
> @@ -33,7 +33,7 @@ struct acm_setpolicy { 
>  struct acm_setpolicy { 
>      /* IN */ 
>      uint32_t interface_version; 
> -    void *pushcache; 
> +    XEN_GUEST_HANDLE(void) pushcache; 
>      uint32_t pushcache_size; 
>  }; 
>   
> @@ -42,7 +42,7 @@ struct acm_getpolicy { 
>  struct acm_getpolicy { 
>      /* IN */ 
>      uint32_t interface_version; 
> -    void *pullcache; 
> +    XEN_GUEST_HANDLE(void) pullcache; 
>      uint32_t pullcache_size; 
>  }; 
>   
> @@ -51,7 +51,7 @@ struct acm_dumpstats { 
>  struct acm_dumpstats { 
>      /* IN */ 
>      uint32_t interface_version; 
> -    void *pullcache; 
> +    XEN_GUEST_HANDLE(void) pullcache; 
>      uint32_t pullcache_size; 
>  }; 
>   
> @@ -61,12 +61,12 @@ struct acm_getssid { 
>  struct acm_getssid { 
>      /* IN */ 
>      uint32_t interface_version; 
> -    enum get_type get_ssid_by; 
> +    uint32_t get_ssid_by; 
>      union { 
>          domaintype_t domainid; 
>          ssidref_t    ssidref; 
>      } id; 
> -    void *ssidbuf; 
> +    XEN_GUEST_HANDLE(void) ssidbuf; 
>      uint32_t ssidbuf_size; 
>  }; 
>   
> @@ -74,8 +74,8 @@ struct acm_getdecision { 
>  struct acm_getdecision { 
>      /* IN */ 
>      uint32_t interface_version; 
> -    enum get_type get_decision_by1; 
> -    enum get_type get_decision_by2; 
> +    uint32_t get_decision_by1; 
> +    uint32_t get_decision_by2; 
>      union { 
>          domaintype_t domainid; 
>          ssidref_t    ssidref; 
> @@ -84,9 +84,9 @@ struct acm_getdecision { 
>          domaintype_t domainid; 
>          ssidref_t    ssidref; 
>      } id2; 
> -    enum acm_hook_type hook; 
> +    uint32_t hook; 
>      /* OUT */ 
> -    int acm_decision; 
> +    uint32_t acm_decision; 
>  }; 
>   
>  #endif /* __XEN_PUBLIC_ACM_OPS_H__ */ 
>  
>  
> --  
> Hollis Blanchard 
> IBM Linux Technology Center 
>  
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
 
 |   
 
 | 
    |