Update kernel to 3.17.4
[hvlinux.git] / stage0 / patches / common / linux-3.17.4-noperl-timeconst.patch
diff --git a/stage0/patches/common/linux-3.17.4-noperl-timeconst.patch b/stage0/patches/common/linux-3.17.4-noperl-timeconst.patch
new file mode 100644 (file)
index 0000000..7925ff8
--- /dev/null
@@ -0,0 +1,252 @@
+Replace timeconst.bc with the c version I've been using for years (to replace
+the perl version). Eventually I should add bc to toybox, but for now...
+
+--- /dev/null
++++ linux/kernel/time/mktimeconst.c
+@@ -0,0 +1,110 @@
++/* Copyright 2010 Parallels Inc, licensed under GPLv2 */
++/* Copyright 2010-2013 Rob Landley <rob@landley.net> */
++
++#include <inttypes.h>
++#include <stdio.h>
++#include <stdlib.h>
++
++int main(int argc, char *argv[])
++{
++      uint64_t hz, periods[] = {1000, 1000000};
++      char *names[] = {"MSEC", "USEC"};
++      FILE *file;
++      int i, j;
++
++      if (argc != 3 || (hz = atol(argv[1])) < 1
++          || !(file = fopen(argv[2], "w")))
++      {
++              fprintf(stderr, "Usage: mktimeconst HZ FILENAME\n\n");
++              fprintf(stderr, "Generate a header file with constants to convert between\n");
++              fprintf(stderr, "decimal HZ timer ticks and milisecond or microsecond delays,\n");
++              fprintf(stderr, "using reciprocal multiplication to avoid 64 bit division.\n");
++              exit(1);
++      }
++
++      fprintf(file,
++              "/* Automatically generated by kernel/mktimeconst */\n"
++              "/* Conversion constants for HZ == %"PRIu64" */\n\n"
++              "#ifndef __KERNEL_TIMECONST_H\n"
++              "#define __KERNEL_TIMECONST_H\n\n"
++              "#include <linux/param.h>\n"
++              "#include <linux/types.h>\n\n"
++              "#if HZ != %"PRIu64"\n"
++              "#error \"kernel/timeconst.h has the wrong HZ value!\"\n"
++              "#endif\n\n", hz, hz);
++
++      /* Repeat for MSEC and USEC */
++
++      for (i = 0; i < 2; i++) {
++              uint64_t gcd, period;
++
++              /* Find greatest common denominator using Euclid's algorithm. */
++
++              gcd = hz;
++              period = periods[i];
++              while (period) {
++                      uint64_t temp = gcd % period;
++                      gcd = period;
++                      period = temp;
++              }
++
++              /* Output both directions (HZ_TO_PERIOD and PERIOD_TO_HZ) */
++
++              for (j = 0; j < 2; j++) {
++                      char name[16];
++                      uint64_t from = j ? periods[i] : hz;
++                      uint64_t to = j ? hz : periods[i];
++                      uint64_t mul32 = 0, adj32 = 0, shift = 0;
++
++                      sprintf(name, j ? "%s_TO_HZ" : "HZ_TO_%s", names[i]);
++
++                      /* Figure out what shift value gives 32 significant
++                         bits of MUL32 data.  (Worst case to=1 from=1000000
++                         uses 52 bits, to<<shift won't overflow 64 bit math.)
++                      */
++
++                      for (;;) {
++                              mul32 = ((to << shift) + from - 1) / from;
++                              if (mul32 >= (1UL<<31))
++                                      break;
++                              shift++;
++                      }
++
++                      /* ADJ32 is is just (((FROM/GCD)-1)<<SHIFT)/(FROM/GCD)
++                         but this can overflow 64 bit math (examples, HZ=24
++                         or HZ=122).  Worst case scenario uses 32+20+20=72
++                         bits.  Workaround: split off bottom 32 bits and
++                         reassemble after calculation (32+64=96 bits). */
++
++                      adj32 = from / gcd;
++
++                      if (shift > 32) {
++                              uint64_t upper, lower;
++
++                              upper = (adj32 - 1) << (shift - 32);
++                              lower = (upper % adj32) << 32;
++                              adj32 = ((upper/adj32) << 32) + (lower/adj32);
++                      } else
++                              adj32 = ((adj32 - 1) << shift) / adj32;
++
++                      /* Emit the constants into the header file. */
++
++                      fprintf(file, "#define %s_MUL32\tU64_C(0x%"PRIx64")\n",
++                              name, mul32);
++                      fprintf(file, "#define %s_ADJ32\tU64_C(0x%"PRIx64")\n",
++                              name, adj32);
++                      fprintf(file, "#define %s_SHR32\t%"PRIu64"\n",
++                              name, shift);
++                      fprintf(file, "#define %s_NUM\t\tU64_C(%"PRIu64")\n",
++                              name, to/gcd);
++                      fprintf(file, "#define %s_DEN\t\tU64_C(%"PRIu64")\n\n",
++                              name, from/gcd);
++              }
++      }
++      fprintf(file, "#endif /* __KERNEL_TIMECONST_H */\n");
++
++      /* Notice if the disk fills up. */
++
++      fflush(stdout);
++      return ferror(stdout);
++}
+--- linux/kernel/time/timeconst.bc     2013-04-28 19:36:01.000000000 -0500
++++ /dev/null  2013-02-23 10:58:11.743993346 -0600
+@@ -1,108 +0,0 @@
+-scale=0
+-
+-define gcd(a,b) {
+-      auto t;
+-      while (b) {
+-              t = b;
+-              b = a % b;
+-              a = t;
+-      }
+-      return a;
+-}
+-
+-/* Division by reciprocal multiplication. */
+-define fmul(b,n,d) {
+-       return (2^b*n+d-1)/d;
+-}
+-
+-/* Adjustment factor when a ceiling value is used.  Use as:
+-   (imul * n) + (fmulxx * n + fadjxx) >> xx) */
+-define fadj(b,n,d) {
+-      auto v;
+-      d = d/gcd(n,d);
+-      v = 2^b*(d-1)/d;
+-      return v;
+-}
+-
+-/* Compute the appropriate mul/adj values as well as a shift count,
+-   which brings the mul value into the range 2^b-1 <= x < 2^b.  Such
+-   a shift value will be correct in the signed integer range and off
+-   by at most one in the upper half of the unsigned range. */
+-define fmuls(b,n,d) {
+-      auto s, m;
+-      for (s = 0; 1; s++) {
+-              m = fmul(s,n,d);
+-              if (m >= 2^(b-1))
+-                      return s;
+-      }
+-      return 0;
+-}
+-
+-define timeconst(hz) {
+-      print "/* Automatically generated by kernel/timeconst.bc */\n"
+-      print "/* Time conversion constants for HZ == ", hz, " */\n"
+-      print "\n"
+-
+-      print "#ifndef KERNEL_TIMECONST_H\n"
+-      print "#define KERNEL_TIMECONST_H\n\n"
+-
+-      print "#include <linux/param.h>\n"
+-      print "#include <linux/types.h>\n\n"
+-
+-      print "#if HZ != ", hz, "\n"
+-      print "#error \qkernel/timeconst.h has the wrong HZ value!\q\n"
+-      print "#endif\n\n"
+-
+-      if (hz < 2) {
+-              print "#error Totally bogus HZ value!\n"
+-      } else {
+-              s=fmuls(32,1000,hz)
+-              obase=16
+-              print "#define HZ_TO_MSEC_MUL32\tU64_C(0x", fmul(s,1000,hz), ")\n"
+-              print "#define HZ_TO_MSEC_ADJ32\tU64_C(0x", fadj(s,1000,hz), ")\n"
+-              obase=10
+-              print "#define HZ_TO_MSEC_SHR32\t", s, "\n"
+-
+-              s=fmuls(32,hz,1000)
+-              obase=16
+-              print "#define MSEC_TO_HZ_MUL32\tU64_C(0x", fmul(s,hz,1000), ")\n"
+-              print "#define MSEC_TO_HZ_ADJ32\tU64_C(0x", fadj(s,hz,1000), ")\n"
+-              obase=10
+-              print "#define MSEC_TO_HZ_SHR32\t", s, "\n"
+-
+-              obase=10
+-              cd=gcd(hz,1000)
+-              print "#define HZ_TO_MSEC_NUM\t\t", 1000/cd, "\n"
+-              print "#define HZ_TO_MSEC_DEN\t\t", hz/cd, "\n"
+-              print "#define MSEC_TO_HZ_NUM\t\t", hz/cd, "\n"
+-              print "#define MSEC_TO_HZ_DEN\t\t", 1000/cd, "\n"
+-              print "\n"
+-
+-              s=fmuls(32,1000000,hz)
+-              obase=16
+-              print "#define HZ_TO_USEC_MUL32\tU64_C(0x", fmul(s,1000000,hz), ")\n"
+-              print "#define HZ_TO_USEC_ADJ32\tU64_C(0x", fadj(s,1000000,hz), ")\n"
+-              obase=10
+-              print "#define HZ_TO_USEC_SHR32\t", s, "\n"
+-
+-              s=fmuls(32,hz,1000000)
+-              obase=16
+-              print "#define USEC_TO_HZ_MUL32\tU64_C(0x", fmul(s,hz,1000000), ")\n"
+-              print "#define USEC_TO_HZ_ADJ32\tU64_C(0x", fadj(s,hz,1000000), ")\n"
+-              obase=10
+-              print "#define USEC_TO_HZ_SHR32\t", s, "\n"
+-
+-              obase=10
+-              cd=gcd(hz,1000000)
+-              print "#define HZ_TO_USEC_NUM\t\t", 1000000/cd, "\n"
+-              print "#define HZ_TO_USEC_DEN\t\t", hz/cd, "\n"
+-              print "#define USEC_TO_HZ_NUM\t\t", hz/cd, "\n"
+-              print "#define USEC_TO_HZ_DEN\t\t", 1000000/cd, "\n"
+-              print "\n"
+-
+-              print "#endif /* KERNEL_TIMECONST_H */\n"
+-      }
+-      halt
+-}
+-
+-timeconst(hz)
+--- linux/kernel/time/Makefile
++++ linux/kernel/time/Makefile
+@@ -125,17 +125,11 @@
+ $(obj)/time.o: $(obj)/timeconst.h
+-quiet_cmd_hzfile = HZFILE  $@
+-      cmd_hzfile = echo "hz=$(CONFIG_HZ)" > $@
+-
+-targets += hz.bc
+-$(obj)/hz.bc: $(objtree)/include/config/hz.h FORCE
+-      $(call if_changed,hzfile)
+-
+-quiet_cmd_bc  = BC      $@
+-      cmd_bc  = bc -q $(filter-out FORCE,$^) > $@
++hostprogs-y    += mktimeconst
++quiet_cmd_mktimeconst = TIMEC   $@
++      cmd_mktimeconst = $(obj)/mktimeconst $(CONFIG_HZ) $@ || ( rm -f $@ && exit 1 )
+ targets += timeconst.h
+-$(obj)/timeconst.h: $(obj)/hz.bc $(src)/timeconst.bc FORCE
+-      $(call if_changed,bc)
++$(obj)/timeconst.h: $(obj)/mktimeconst FORCE
++      $(call if_changed,mktimeconst)