direct-io.hg

changeset 8512:b866ed85fad3

Add cpumask_scnprintf() and cpulist_scnprintf(). This also
adds the bitmap_scnprintf functions and scnprintf itself.

Add dirty cpu and cpu affinity info to 'q'-key debug output.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sat Jan 07 18:17:13 2006 +0100 (2006-01-07)
parents 4c2c02ca4a7a
children 299d6ff8fdb2
files xen/common/bitmap.c xen/common/keyhandler.c xen/common/vsprintf.c xen/include/xen/bitmap.h xen/include/xen/cpumask.h xen/include/xen/lib.h
line diff
     1.1 --- a/xen/common/bitmap.c	Sat Jan 07 18:16:10 2006 +0100
     1.2 +++ b/xen/common/bitmap.c	Sat Jan 07 18:17:13 2006 +0100
     1.3 @@ -282,6 +282,111 @@ int __bitmap_weight(const unsigned long 
     1.4  #endif
     1.5  EXPORT_SYMBOL(__bitmap_weight);
     1.6  
     1.7 +/*
     1.8 + * Bitmap printing & parsing functions: first version by Bill Irwin,
     1.9 + * second version by Paul Jackson, third by Joe Korty.
    1.10 + */
    1.11 +
    1.12 +#define CHUNKSZ				32
    1.13 +#define nbits_to_hold_value(val)	fls(val)
    1.14 +#define roundup_power2(val,modulus)	(((val) + (modulus) - 1) & ~((modulus) - 1))
    1.15 +#define unhex(c)			(isdigit(c) ? (c - '0') : (toupper(c) - 'A' + 10))
    1.16 +#define BASEDEC 10		/* fancier cpuset lists input in decimal */
    1.17 +
    1.18 +/**
    1.19 + * bitmap_scnprintf - convert bitmap to an ASCII hex string.
    1.20 + * @buf: byte buffer into which string is placed
    1.21 + * @buflen: reserved size of @buf, in bytes
    1.22 + * @maskp: pointer to bitmap to convert
    1.23 + * @nmaskbits: size of bitmap, in bits
    1.24 + *
    1.25 + * Exactly @nmaskbits bits are displayed.  Hex digits are grouped into
    1.26 + * comma-separated sets of eight digits per set.
    1.27 + */
    1.28 +int bitmap_scnprintf(char *buf, unsigned int buflen,
    1.29 +	const unsigned long *maskp, int nmaskbits)
    1.30 +{
    1.31 +	int i, word, bit, len = 0;
    1.32 +	unsigned long val;
    1.33 +	const char *sep = "";
    1.34 +	int chunksz;
    1.35 +	u32 chunkmask;
    1.36 +
    1.37 +	chunksz = nmaskbits & (CHUNKSZ - 1);
    1.38 +	if (chunksz == 0)
    1.39 +		chunksz = CHUNKSZ;
    1.40 +
    1.41 +	i = roundup_power2(nmaskbits, CHUNKSZ) - CHUNKSZ;
    1.42 +	for (; i >= 0; i -= CHUNKSZ) {
    1.43 +		chunkmask = ((1ULL << chunksz) - 1);
    1.44 +		word = i / BITS_PER_LONG;
    1.45 +		bit = i % BITS_PER_LONG;
    1.46 +		val = (maskp[word] >> bit) & chunkmask;
    1.47 +		len += scnprintf(buf+len, buflen-len, "%s%0*lx", sep,
    1.48 +			(chunksz+3)/4, val);
    1.49 +		chunksz = CHUNKSZ;
    1.50 +		sep = ",";
    1.51 +	}
    1.52 +	return len;
    1.53 +}
    1.54 +EXPORT_SYMBOL(bitmap_scnprintf);
    1.55 +
    1.56 +/*
    1.57 + * bscnl_emit(buf, buflen, rbot, rtop, bp)
    1.58 + *
    1.59 + * Helper routine for bitmap_scnlistprintf().  Write decimal number
    1.60 + * or range to buf, suppressing output past buf+buflen, with optional
    1.61 + * comma-prefix.  Return len of what would be written to buf, if it
    1.62 + * all fit.
    1.63 + */
    1.64 +static inline int bscnl_emit(char *buf, int buflen, int rbot, int rtop, int len)
    1.65 +{
    1.66 +	if (len > 0)
    1.67 +		len += scnprintf(buf + len, buflen - len, ",");
    1.68 +	if (rbot == rtop)
    1.69 +		len += scnprintf(buf + len, buflen - len, "%d", rbot);
    1.70 +	else
    1.71 +		len += scnprintf(buf + len, buflen - len, "%d-%d", rbot, rtop);
    1.72 +	return len;
    1.73 +}
    1.74 +
    1.75 +/**
    1.76 + * bitmap_scnlistprintf - convert bitmap to list format ASCII string
    1.77 + * @buf: byte buffer into which string is placed
    1.78 + * @buflen: reserved size of @buf, in bytes
    1.79 + * @maskp: pointer to bitmap to convert
    1.80 + * @nmaskbits: size of bitmap, in bits
    1.81 + *
    1.82 + * Output format is a comma-separated list of decimal numbers and
    1.83 + * ranges.  Consecutively set bits are shown as two hyphen-separated
    1.84 + * decimal numbers, the smallest and largest bit numbers set in
    1.85 + * the range.  Output format is compatible with the format
    1.86 + * accepted as input by bitmap_parselist().
    1.87 + *
    1.88 + * The return value is the number of characters which would be
    1.89 + * generated for the given input, excluding the trailing '\0', as
    1.90 + * per ISO C99.
    1.91 + */
    1.92 +int bitmap_scnlistprintf(char *buf, unsigned int buflen,
    1.93 +	const unsigned long *maskp, int nmaskbits)
    1.94 +{
    1.95 +	int len = 0;
    1.96 +	/* current bit is 'cur', most recently seen range is [rbot, rtop] */
    1.97 +	int cur, rbot, rtop;
    1.98 +
    1.99 +	rbot = cur = find_first_bit(maskp, nmaskbits);
   1.100 +	while (cur < nmaskbits) {
   1.101 +		rtop = cur;
   1.102 +		cur = find_next_bit(maskp, nmaskbits, cur+1);
   1.103 +		if (cur >= nmaskbits || cur > rtop + 1) {
   1.104 +			len = bscnl_emit(buf, buflen, rbot, rtop, len);
   1.105 +			rbot = cur;
   1.106 +		}
   1.107 +	}
   1.108 +	return len;
   1.109 +}
   1.110 +EXPORT_SYMBOL(bitmap_scnlistprintf);
   1.111 +
   1.112  /**
   1.113   *	bitmap_find_free_region - find a contiguous aligned mem region
   1.114   *	@bitmap: an array of unsigned longs corresponding to the bitmap
     2.1 --- a/xen/common/keyhandler.c	Sat Jan 07 18:16:10 2006 +0100
     2.2 +++ b/xen/common/keyhandler.c	Sat Jan 07 18:17:13 2006 +0100
     2.3 @@ -97,13 +97,22 @@ static void halt_machine(unsigned char k
     2.4      machine_restart(NULL); 
     2.5  }
     2.6  
     2.7 -static void do_task_queues(unsigned char key)
     2.8 +static void cpuset_print(char *set, int size, cpumask_t mask)
     2.9 +{
    2.10 +    *set++ = '{';
    2.11 +    set += cpulist_scnprintf(set, size-2, mask);
    2.12 +    *set++ = '}';
    2.13 +    *set++ = '\0';
    2.14 +}
    2.15 +
    2.16 +static void dump_domains(unsigned char key)
    2.17  {
    2.18      struct domain *d;
    2.19      struct vcpu   *v;
    2.20      s_time_t       now = NOW();
    2.21 +    char           cpuset[100];
    2.22  
    2.23 -    printk("'%c' pressed -> dumping task queues (now=0x%X:%08X)\n", key,
    2.24 +    printk("'%c' pressed -> dumping domain info (now=0x%X:%08X)\n", key,
    2.25             (u32)(now>>32), (u32)now); 
    2.26  
    2.27      read_lock(&domlist_lock);
    2.28 @@ -111,9 +120,11 @@ static void do_task_queues(unsigned char
    2.29      for_each_domain ( d )
    2.30      {
    2.31          printk("General information for domain %u:\n", d->domain_id);
    2.32 -        printk("    flags=%lx refcnt=%d nr_pages=%d xenheap_pages=%d\n",
    2.33 +        cpuset_print(cpuset, sizeof(cpuset), d->domain_dirty_cpumask);
    2.34 +        printk("    flags=%lx refcnt=%d nr_pages=%d xenheap_pages=%d "
    2.35 +               "dirty_cpus=%s\n",
    2.36                 d->domain_flags, atomic_read(&d->refcnt),
    2.37 -               d->tot_pages, d->xenheap_pages);
    2.38 +               d->tot_pages, d->xenheap_pages, cpuset);
    2.39          printk("    handle=%02x%02x%02x%02x-%02x%02x-%02x%02x-"
    2.40                 "%02x%02x-%02x%02x%02x%02x%02x%02x\n",
    2.41                 d->handle[ 0], d->handle[ 1], d->handle[ 2], d->handle[ 3],
    2.42 @@ -129,12 +140,16 @@ static void do_task_queues(unsigned char
    2.43                 d->domain_id);
    2.44          for_each_vcpu ( d, v ) {
    2.45              printk("    VCPU%d: CPU%d [has=%c] flags=%lx "
    2.46 -                   "upcall_pend = %02x, upcall_mask = %02x\n",
    2.47 +                   "upcall_pend = %02x, upcall_mask = %02x ",
    2.48                     v->vcpu_id, v->processor,
    2.49                     test_bit(_VCPUF_running, &v->vcpu_flags) ? 'T':'F',
    2.50                     v->vcpu_flags,
    2.51                     v->vcpu_info->evtchn_upcall_pending, 
    2.52                     v->vcpu_info->evtchn_upcall_mask);
    2.53 +            cpuset_print(cpuset, sizeof(cpuset), v->vcpu_dirty_cpumask);
    2.54 +            printk("dirty_cpus=%s ", cpuset);
    2.55 +            cpuset_print(cpuset, sizeof(cpuset), v->cpu_affinity);
    2.56 +            printk("cpu_affinity=%s\n", cpuset);
    2.57              printk("    Notifying guest (virq %d, port %d, stat %d/%d/%d)\n",
    2.58                     VIRQ_DEBUG, v->virq_to_evtchn[VIRQ_DEBUG],
    2.59                     test_bit(v->virq_to_evtchn[VIRQ_DEBUG], 
    2.60 @@ -193,7 +208,7 @@ void initialize_keytable(void)
    2.61      register_keyhandler(
    2.62          'L', reset_sched_histo, "reset sched latency histogram");
    2.63      register_keyhandler(
    2.64 -        'q', do_task_queues, "dump task queues + guest state");
    2.65 +        'q', dump_domains, "dump domain (and guest debug) info");
    2.66      register_keyhandler(
    2.67          'r', dump_runq,      "dump run queues");
    2.68      register_irq_keyhandler(
     3.1 --- a/xen/common/vsprintf.c	Sat Jan 07 18:16:10 2006 +0100
     3.2 +++ b/xen/common/vsprintf.c	Sat Jan 07 18:17:13 2006 +0100
     3.3 @@ -12,11 +12,15 @@
     3.4  /* 
     3.5   * Fri Jul 13 2001 Crutcher Dunnavant <crutcher+kernel@datastacks.com>
     3.6   * - changed to provide snprintf and vsnprintf functions
     3.7 + * So Feb  1 16:51:32 CET 2004 Juergen Quade <quade@hsnr.de>
     3.8 + * - scnprintf and vscnprintf
     3.9   */
    3.10  
    3.11  #include <stdarg.h>
    3.12  #include <xen/ctype.h>
    3.13  #include <xen/lib.h>
    3.14 +#include <asm/div64.h>
    3.15 +#include <asm/page.h>
    3.16  
    3.17  /**
    3.18   * simple_strtoul - convert a string to an unsigned long
    3.19 @@ -33,11 +37,14 @@ unsigned long simple_strtoul(const char 
    3.20          if (*cp == '0') {
    3.21              base = 8;
    3.22              cp++;
    3.23 -            if ((*cp == 'x') && isxdigit(cp[1])) {
    3.24 +            if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
    3.25                  cp++;
    3.26                  base = 16;
    3.27              }
    3.28          }
    3.29 +    } else if (base == 16) {
    3.30 +        if (cp[0] == '0' && toupper(cp[1]) == 'X')
    3.31 +            cp += 2;
    3.32      }
    3.33      while (isxdigit(*cp) &&
    3.34             (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) {
    3.35 @@ -49,6 +56,8 @@ unsigned long simple_strtoul(const char 
    3.36      return result;
    3.37  }
    3.38  
    3.39 +EXPORT_SYMBOL(simple_strtoul);
    3.40 +
    3.41  /**
    3.42   * simple_strtol - convert a string to a signed long
    3.43   * @cp: The start of the string
    3.44 @@ -62,6 +71,8 @@ long simple_strtol(const char *cp,char *
    3.45      return simple_strtoul(cp,endp,base);
    3.46  }
    3.47  
    3.48 +EXPORT_SYMBOL(simple_strtol);
    3.49 +
    3.50  /**
    3.51   * simple_strtoull - convert a string to an unsigned long long
    3.52   * @cp: The start of the string
    3.53 @@ -77,11 +88,14 @@ unsigned long long simple_strtoull(const
    3.54          if (*cp == '0') {
    3.55              base = 8;
    3.56              cp++;
    3.57 -            if ((*cp == 'x') && isxdigit(cp[1])) {
    3.58 +            if ((toupper(*cp) == 'X') && isxdigit(cp[1])) {
    3.59                  cp++;
    3.60                  base = 16;
    3.61              }
    3.62          }
    3.63 +    } else if (base == 16) {
    3.64 +        if (cp[0] == '0' && toupper(cp[1]) == 'X')
    3.65 +            cp += 2;
    3.66      }
    3.67      while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp-'0' : (islower(*cp)
    3.68                                                                 ? toupper(*cp) : *cp)-'A'+10) < base) {
    3.69 @@ -93,6 +107,8 @@ unsigned long long simple_strtoull(const
    3.70      return result;
    3.71  }
    3.72  
    3.73 +EXPORT_SYMBOL(simple_strtoull);
    3.74 +
    3.75  /**
    3.76   * simple_strtoll - convert a string to a signed long long
    3.77   * @cp: The start of the string
    3.78 @@ -123,25 +139,25 @@ static int skip_atoi(const char **s)
    3.79  #define SPECIAL 32              /* 0x */
    3.80  #define LARGE   64              /* use 'ABCDEF' instead of 'abcdef' */
    3.81  
    3.82 -static char * number(char * buf, char * end, long long num, int base, int size, int precision, int type)
    3.83 +static char * number(char * buf, char * end, unsigned long long num, int base, int size, int precision, int type)
    3.84  {
    3.85      char c,sign,tmp[66];
    3.86      const char *digits;
    3.87 -    const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
    3.88 -    const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    3.89 +    static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
    3.90 +    static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    3.91      int i;
    3.92  
    3.93      digits = (type & LARGE) ? large_digits : small_digits;
    3.94      if (type & LEFT)
    3.95          type &= ~ZEROPAD;
    3.96      if (base < 2 || base > 36)
    3.97 -        return buf;
    3.98 +        return NULL;
    3.99      c = (type & ZEROPAD) ? '0' : ' ';
   3.100      sign = 0;
   3.101      if (type & SIGN) {
   3.102 -        if (num < 0) {
   3.103 +        if ((signed long long) num < 0) {
   3.104              sign = '-';
   3.105 -            num = -num;
   3.106 +            num = - (signed long long) num;
   3.107              size--;
   3.108          } else if (type & PLUS) {
   3.109              sign = '+';
   3.110 @@ -160,6 +176,9 @@ static char * number(char * buf, char * 
   3.111      i = 0;
   3.112      if (num == 0)
   3.113          tmp[i++]='0';
   3.114 +    else while (num != 0)
   3.115 +        tmp[i++] = digits[do_div(num,base)];
   3.116 +#if 0
   3.117      else 
   3.118      {
   3.119          /* XXX KAF: force unsigned mod and div. */
   3.120 @@ -167,6 +186,7 @@ static char * number(char * buf, char * 
   3.121          unsigned int base2=(unsigned int)base;
   3.122          while (num2 != 0) { tmp[i++] = digits[num2%base2]; num2 /= base2; }
   3.123      }
   3.124 +#endif
   3.125      if (i > precision)
   3.126          precision = i;
   3.127      size -= precision;
   3.128 @@ -222,14 +242,22 @@ static char * number(char * buf, char * 
   3.129  }
   3.130  
   3.131  /**
   3.132 -* vsnprintf - Format a string and place it in a buffer
   3.133 -* @buf: The buffer to place the result into
   3.134 -* @size: The size of the buffer, including the trailing null space
   3.135 -* @fmt: The format string to use
   3.136 -* @args: Arguments for the format string
   3.137 -*
   3.138 -* Call this function if you are already dealing with a va_list.
   3.139 -* You probably want snprintf instead.
   3.140 + * vsnprintf - Format a string and place it in a buffer
   3.141 + * @buf: The buffer to place the result into
   3.142 + * @size: The size of the buffer, including the trailing null space
   3.143 + * @fmt: The format string to use
   3.144 + * @args: Arguments for the format string
   3.145 + *
   3.146 + * The return value is the number of characters which would
   3.147 + * be generated for the given input, excluding the trailing
   3.148 + * '\0', as per ISO C99. If you want to have the exact
   3.149 + * number of characters written into @buf as return value
   3.150 + * (not including the trailing '\0'), use vscnprintf. If the
   3.151 + * return is greater than or equal to @size, the resulting
   3.152 + * string is truncated.
   3.153 + *
   3.154 + * Call this function if you are already dealing with a va_list.
   3.155 + * You probably want snprintf instead.
   3.156   */
   3.157  int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
   3.158  {
   3.159 @@ -248,6 +276,9 @@ int vsnprintf(char *buf, size_t size, co
   3.160                                  /* 'z' support added 23/7/1999 S.H.    */
   3.161                                  /* 'z' changed to 'Z' --davidm 1/25/99 */
   3.162  
   3.163 +    /* Reject out-of-range values early */
   3.164 +    BUG_ON((int)size < 0);
   3.165 +
   3.166      str = buf;
   3.167      end = buf + size - 1;
   3.168  
   3.169 @@ -307,7 +338,8 @@ int vsnprintf(char *buf, size_t size, co
   3.170  
   3.171          /* get the conversion qualifier */
   3.172          qualifier = -1;
   3.173 -        if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') {
   3.174 +        if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
   3.175 +            *fmt =='Z' || *fmt == 'z') {
   3.176              qualifier = *fmt;
   3.177              ++fmt;
   3.178              if (qualifier == 'l' && *fmt == 'l') {
   3.179 @@ -315,10 +347,6 @@ int vsnprintf(char *buf, size_t size, co
   3.180                  ++fmt;
   3.181              }
   3.182          }
   3.183 -        if (*fmt == 'q') {
   3.184 -            qualifier = 'L';
   3.185 -            ++fmt;
   3.186 -        }
   3.187  
   3.188          /* default base */
   3.189          base = 10;
   3.190 @@ -345,7 +373,7 @@ int vsnprintf(char *buf, size_t size, co
   3.191  
   3.192          case 's':
   3.193              s = va_arg(args, char *);
   3.194 -            if (!s)
   3.195 +            if ((unsigned long)s < PAGE_SIZE)
   3.196                  s = "<NULL>";
   3.197  
   3.198              len = strnlen(s, precision);
   3.199 @@ -386,7 +414,7 @@ int vsnprintf(char *buf, size_t size, co
   3.200              if (qualifier == 'l') {
   3.201                  long * ip = va_arg(args, long *);
   3.202                  *ip = (str - buf);
   3.203 -            } else if (qualifier == 'Z') {
   3.204 +            } else if (qualifier == 'Z' || qualifier == 'z') {
   3.205                  size_t * ip = va_arg(args, size_t *);
   3.206                  *ip = (str - buf);
   3.207              } else {
   3.208 @@ -437,7 +465,7 @@ int vsnprintf(char *buf, size_t size, co
   3.209              num = va_arg(args, unsigned long);
   3.210              if (flags & SIGN)
   3.211                  num = (signed long) num;
   3.212 -        } else if (qualifier == 'Z') {
   3.213 +        } else if (qualifier == 'Z' || qualifier == 'z') {
   3.214              num = va_arg(args, size_t);
   3.215          } else if (qualifier == 'h') {
   3.216              num = (unsigned short) va_arg(args, int);
   3.217 @@ -463,12 +491,43 @@ int vsnprintf(char *buf, size_t size, co
   3.218      return str-buf;
   3.219  }
   3.220  
   3.221 +EXPORT_SYMBOL(vsnprintf);
   3.222 +
   3.223 +/**
   3.224 + * vscnprintf - Format a string and place it in a buffer
   3.225 + * @buf: The buffer to place the result into
   3.226 + * @size: The size of the buffer, including the trailing null space
   3.227 + * @fmt: The format string to use
   3.228 + * @args: Arguments for the format string
   3.229 + *
   3.230 + * The return value is the number of characters which have been written into
   3.231 + * the @buf not including the trailing '\0'. If @size is <= 0 the function
   3.232 + * returns 0.
   3.233 + *
   3.234 + * Call this function if you are already dealing with a va_list.
   3.235 + * You probably want scnprintf instead.
   3.236 + */
   3.237 +int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
   3.238 +{
   3.239 +    int i;
   3.240 +
   3.241 +    i=vsnprintf(buf,size,fmt,args);
   3.242 +    return (i >= size) ? (size - 1) : i;
   3.243 +}
   3.244 +
   3.245 +EXPORT_SYMBOL(vscnprintf);
   3.246 +
   3.247  /**
   3.248   * snprintf - Format a string and place it in a buffer
   3.249   * @buf: The buffer to place the result into
   3.250   * @size: The size of the buffer, including the trailing null space
   3.251   * @fmt: The format string to use
   3.252   * @...: Arguments for the format string
   3.253 + *
   3.254 + * The return value is the number of characters which would be
   3.255 + * generated for the given input, excluding the trailing null,
   3.256 + * as per ISO C99.  If the return is greater than or equal to
   3.257 + * @size, the resulting string is truncated.
   3.258   */
   3.259  int snprintf(char * buf, size_t size, const char *fmt, ...)
   3.260  {
   3.261 @@ -481,26 +540,61 @@ int snprintf(char * buf, size_t size, co
   3.262      return i;
   3.263  }
   3.264  
   3.265 +EXPORT_SYMBOL(snprintf);
   3.266 +
   3.267 +/**
   3.268 + * scnprintf - Format a string and place it in a buffer
   3.269 + * @buf: The buffer to place the result into
   3.270 + * @size: The size of the buffer, including the trailing null space
   3.271 + * @fmt: The format string to use
   3.272 + * @...: Arguments for the format string
   3.273 + *
   3.274 + * The return value is the number of characters written into @buf not including
   3.275 + * the trailing '\0'. If @size is <= 0 the function returns 0. If the return is
   3.276 + * greater than or equal to @size, the resulting string is truncated.
   3.277 + */
   3.278 +
   3.279 +int scnprintf(char * buf, size_t size, const char *fmt, ...)
   3.280 +{
   3.281 +    va_list args;
   3.282 +    int i;
   3.283 +
   3.284 +    va_start(args, fmt);
   3.285 +    i = vsnprintf(buf, size, fmt, args);
   3.286 +    va_end(args);
   3.287 +    return (i >= size) ? (size - 1) : i;
   3.288 +}
   3.289 +EXPORT_SYMBOL(scnprintf);
   3.290 +
   3.291  /**
   3.292   * vsprintf - Format a string and place it in a buffer
   3.293   * @buf: The buffer to place the result into
   3.294   * @fmt: The format string to use
   3.295   * @args: Arguments for the format string
   3.296   *
   3.297 + * The function returns the number of characters written
   3.298 + * into @buf. Use vsnprintf or vscnprintf in order to avoid
   3.299 + * buffer overflows.
   3.300 + *
   3.301   * Call this function if you are already dealing with a va_list.
   3.302   * You probably want sprintf instead.
   3.303   */
   3.304  int vsprintf(char *buf, const char *fmt, va_list args)
   3.305  {
   3.306 -    return vsnprintf(buf, 0xFFFFFFFFUL, fmt, args);
   3.307 +    return vsnprintf(buf, INT_MAX, fmt, args);
   3.308  }
   3.309  
   3.310 +EXPORT_SYMBOL(vsprintf);
   3.311  
   3.312  /**
   3.313   * sprintf - Format a string and place it in a buffer
   3.314   * @buf: The buffer to place the result into
   3.315   * @fmt: The format string to use
   3.316   * @...: Arguments for the format string
   3.317 + *
   3.318 + * The function returns the number of characters written
   3.319 + * into @buf. Use snprintf or scnprintf in order to avoid
   3.320 + * buffer overflows.
   3.321   */
   3.322  int sprintf(char * buf, const char *fmt, ...)
   3.323  {
   3.324 @@ -508,11 +602,12 @@ int sprintf(char * buf, const char *fmt,
   3.325      int i;
   3.326  
   3.327      va_start(args, fmt);
   3.328 -    i=vsprintf(buf,fmt,args);
   3.329 +    i=vsnprintf(buf, INT_MAX, fmt, args);
   3.330      va_end(args);
   3.331      return i;
   3.332  }
   3.333  
   3.334 +EXPORT_SYMBOL(sprintf);
   3.335  
   3.336  /*
   3.337   * Local variables:
     4.1 --- a/xen/include/xen/bitmap.h	Sat Jan 07 18:16:10 2006 +0100
     4.2 +++ b/xen/include/xen/bitmap.h	Sat Jan 07 18:17:13 2006 +0100
     4.3 @@ -41,6 +41,8 @@
     4.4   * bitmap_weight(src, nbits)			Hamming Weight: number set bits
     4.5   * bitmap_shift_right(dst, src, n, nbits)	*dst = *src >> n
     4.6   * bitmap_shift_left(dst, src, n, nbits)	*dst = *src << n
     4.7 + * bitmap_scnprintf(buf, len, src, nbits)	Print bitmap src to buf
     4.8 + * bitmap_scnlistprintf(buf, len, src, nbits)	Print bitmap src as list to buf
     4.9   */
    4.10  
    4.11  /*
    4.12 @@ -93,6 +95,10 @@ extern int __bitmap_subset(const unsigne
    4.13  			const unsigned long *bitmap2, int bits);
    4.14  extern int __bitmap_weight(const unsigned long *bitmap, int bits);
    4.15  
    4.16 +extern int bitmap_scnprintf(char *buf, unsigned int len,
    4.17 +			const unsigned long *src, int nbits);
    4.18 +extern int bitmap_scnlistprintf(char *buf, unsigned int len,
    4.19 +			const unsigned long *src, int nbits);
    4.20  extern int bitmap_find_free_region(unsigned long *bitmap, int bits, int order);
    4.21  extern void bitmap_release_region(unsigned long *bitmap, int pos, int order);
    4.22  extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order);
     5.1 --- a/xen/include/xen/cpumask.h	Sat Jan 07 18:16:10 2006 +0100
     5.2 +++ b/xen/include/xen/cpumask.h	Sat Jan 07 18:17:13 2006 +0100
     5.3 @@ -8,8 +8,8 @@
     5.4   * See detailed comments in the file xen/bitmap.h describing the
     5.5   * data type on which these cpumasks are based.
     5.6   *
     5.7 - * For details of cpumask_scnprintf() and cpumask_parse(),
     5.8 - * see bitmap_scnprintf() and bitmap_parse() in lib/bitmap.c.
     5.9 + * For details of cpumask_scnprintf() and cpulist_scnprintf(),
    5.10 + * see bitmap_scnprintf() and bitmap_scnlistprintf() in lib/bitmap.c.
    5.11   *
    5.12   * The available cpumask operations are:
    5.13   *
    5.14 @@ -36,8 +36,8 @@
    5.15   * void cpus_shift_right(dst, src, n)	Shift right
    5.16   * void cpus_shift_left(dst, src, n)	Shift left
    5.17   *
    5.18 - * int first_cpu(mask)			Number lowest set bit, or >= NR_CPUS
    5.19 - * int next_cpu(cpu, mask)		Next cpu past 'cpu', or >= NR_CPUS
    5.20 + * int first_cpu(mask)			Number lowest set bit, or NR_CPUS
    5.21 + * int next_cpu(cpu, mask)		Next cpu past 'cpu', or NR_CPUS
    5.22   *
    5.23   * cpumask_t cpumask_of_cpu(cpu)	Return cpumask with bit 'cpu' set
    5.24   * CPU_MASK_ALL				Initializer - all bits set
    5.25 @@ -45,7 +45,7 @@
    5.26   * unsigned long *cpus_addr(mask)	Array of unsigned long's in mask
    5.27   *
    5.28   * int cpumask_scnprintf(buf, len, mask) Format cpumask for printing
    5.29 - * int cpumask_parse(ubuf, ulen, mask)	Parse ascii string as cpumask
    5.30 + * int cpulist_scnprintf(buf, len, mask) Format cpumask as list for printing
    5.31   *
    5.32   * for_each_cpu_mask(cpu, mask)		for-loop cpu over mask
    5.33   *
    5.34 @@ -207,13 +207,13 @@ static inline void __cpus_shift_left(cpu
    5.35  #define first_cpu(src) __first_cpu(&(src), NR_CPUS)
    5.36  static inline int __first_cpu(const cpumask_t *srcp, int nbits)
    5.37  {
    5.38 -	return find_first_bit(srcp->bits, nbits);
    5.39 +	return min_t(int, nbits, find_first_bit(srcp->bits, nbits));
    5.40  }
    5.41  
    5.42  #define next_cpu(n, src) __next_cpu((n), &(src), NR_CPUS)
    5.43  static inline int __next_cpu(int n, const cpumask_t *srcp, int nbits)
    5.44  {
    5.45 -	return find_next_bit(srcp->bits, nbits, n+1);
    5.46 +	return min_t(int, nbits, find_next_bit(srcp->bits, nbits, n+1));
    5.47  }
    5.48  
    5.49  #define cpumask_of_cpu(cpu)						\
    5.50 @@ -259,7 +259,6 @@ static inline int __next_cpu(int n, cons
    5.51  
    5.52  #define cpus_addr(src) ((src).bits)
    5.53  
    5.54 -/*
    5.55  #define cpumask_scnprintf(buf, len, src) \
    5.56  			__cpumask_scnprintf((buf), (len), &(src), NR_CPUS)
    5.57  static inline int __cpumask_scnprintf(char *buf, int len,
    5.58 @@ -268,14 +267,13 @@ static inline int __cpumask_scnprintf(ch
    5.59  	return bitmap_scnprintf(buf, len, srcp->bits, nbits);
    5.60  }
    5.61  
    5.62 -#define cpumask_parse(ubuf, ulen, src) \
    5.63 -			__cpumask_parse((ubuf), (ulen), &(src), NR_CPUS)
    5.64 -static inline int __cpumask_parse(const char __user *buf, int len,
    5.65 -					cpumask_t *dstp, int nbits)
    5.66 +#define cpulist_scnprintf(buf, len, src) \
    5.67 +			__cpulist_scnprintf((buf), (len), &(src), NR_CPUS)
    5.68 +static inline int __cpulist_scnprintf(char *buf, int len,
    5.69 +					const cpumask_t *srcp, int nbits)
    5.70  {
    5.71 -	return bitmap_parse(buf, len, dstp->bits, nbits);
    5.72 +	return bitmap_scnlistprintf(buf, len, srcp->bits, nbits);
    5.73  }
    5.74 -*/
    5.75  
    5.76  #if NR_CPUS > 1
    5.77  #define for_each_cpu_mask(cpu, mask)		\
    5.78 @@ -368,7 +366,7 @@ extern cpumask_t cpu_present_map;
    5.79  	for_each_cpu_mask(cpu, (mask))		\
    5.80  		if (cpu_online(cpu))		\
    5.81  			break;			\
    5.82 -	min_t(int, NR_CPUS, cpu);		\
    5.83 +	cpu;					\
    5.84  })
    5.85  
    5.86  #define for_each_cpu(cpu)	  for_each_cpu_mask((cpu), cpu_possible_map)
     6.1 --- a/xen/include/xen/lib.h	Sat Jan 07 18:16:10 2006 +0100
     6.2 +++ b/xen/include/xen/lib.h	Sat Jan 07 18:17:13 2006 +0100
     6.3 @@ -53,10 +53,16 @@ extern long vm_assist(struct domain *, u
     6.4  /* vsprintf.c */
     6.5  extern int sprintf(char * buf, const char * fmt, ...)
     6.6      __attribute__ ((format (printf, 2, 3)));
     6.7 -extern int vsprintf(char *buf, const char *, va_list);
     6.8 +extern int vsprintf(char *buf, const char *, va_list)
     6.9 +    __attribute__ ((format (printf, 2, 0)));
    6.10  extern int snprintf(char * buf, size_t size, const char * fmt, ...)
    6.11      __attribute__ ((format (printf, 3, 4)));
    6.12 -extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
    6.13 +extern int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
    6.14 +    __attribute__ ((format (printf, 3, 0)));
    6.15 +extern int scnprintf(char * buf, size_t size, const char * fmt, ...)
    6.16 +    __attribute__ ((format (printf, 3, 4)));
    6.17 +extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
    6.18 +    __attribute__ ((format (printf, 3, 0)));
    6.19  
    6.20  long simple_strtol(
    6.21      const char *cp,char **endp, unsigned int base);