Merge tag 'for_linus-4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel...
[sfrench/cifs-2.6.git] / kernel / debug / kdb / kdb_main.c
index dbb0781a053364824f5361d07cfc72cf9fe0a2e2..e405677ee08d6ae6b71c36afd2270d2ed806810d 100644 (file)
@@ -1150,6 +1150,16 @@ void kdb_set_current_task(struct task_struct *p)
        kdb_current_regs = NULL;
 }
 
+static void drop_newline(char *buf)
+{
+       size_t len = strlen(buf);
+
+       if (len == 0)
+               return;
+       if (*(buf + len - 1) == '\n')
+               *(buf + len - 1) = '\0';
+}
+
 /*
  * kdb_local - The main code for kdb.  This routine is invoked on a
  *     specific processor, it is not global.  The main kdb() routine
@@ -1327,6 +1337,7 @@ do_full_getstr:
                cmdptr = cmd_head;
                diag = kdb_parse(cmdbuf);
                if (diag == KDB_NOTFOUND) {
+                       drop_newline(cmdbuf);
                        kdb_printf("Unknown kdb command: '%s'\n", cmdbuf);
                        diag = 0;
                }
@@ -1566,6 +1577,7 @@ static int kdb_md(int argc, const char **argv)
        int symbolic = 0;
        int valid = 0;
        int phys = 0;
+       int raw = 0;
 
        kdbgetintenv("MDCOUNT", &mdcount);
        kdbgetintenv("RADIX", &radix);
@@ -1575,9 +1587,10 @@ static int kdb_md(int argc, const char **argv)
        repeat = mdcount * 16 / bytesperword;
 
        if (strcmp(argv[0], "mdr") == 0) {
-               if (argc != 2)
+               if (argc == 2 || (argc == 0 && last_addr != 0))
+                       valid = raw = 1;
+               else
                        return KDB_ARGCOUNT;
-               valid = 1;
        } else if (isdigit(argv[0][2])) {
                bytesperword = (int)(argv[0][2] - '0');
                if (bytesperword == 0) {
@@ -1613,7 +1626,10 @@ static int kdb_md(int argc, const char **argv)
                radix = last_radix;
                bytesperword = last_bytesperword;
                repeat = last_repeat;
-               mdcount = ((repeat * bytesperword) + 15) / 16;
+               if (raw)
+                       mdcount = repeat;
+               else
+                       mdcount = ((repeat * bytesperword) + 15) / 16;
        }
 
        if (argc) {
@@ -1630,7 +1646,10 @@ static int kdb_md(int argc, const char **argv)
                        diag = kdbgetularg(argv[nextarg], &val);
                        if (!diag) {
                                mdcount = (int) val;
-                               repeat = mdcount * 16 / bytesperword;
+                               if (raw)
+                                       repeat = mdcount;
+                               else
+                                       repeat = mdcount * 16 / bytesperword;
                        }
                }
                if (argc >= nextarg+1) {
@@ -1640,8 +1659,15 @@ static int kdb_md(int argc, const char **argv)
                }
        }
 
-       if (strcmp(argv[0], "mdr") == 0)
-               return kdb_mdr(addr, mdcount);
+       if (strcmp(argv[0], "mdr") == 0) {
+               int ret;
+               last_addr = addr;
+               ret = kdb_mdr(addr, mdcount);
+               last_addr += mdcount;
+               last_repeat = mdcount;
+               last_bytesperword = bytesperword; // to make REPEAT happy
+               return ret;
+       }
 
        switch (radix) {
        case 10:
@@ -2473,41 +2499,6 @@ static int kdb_kill(int argc, const char **argv)
        return 0;
 }
 
-struct kdb_tm {
-       int tm_sec;     /* seconds */
-       int tm_min;     /* minutes */
-       int tm_hour;    /* hours */
-       int tm_mday;    /* day of the month */
-       int tm_mon;     /* month */
-       int tm_year;    /* year */
-};
-
-static void kdb_gmtime(struct timespec *tv, struct kdb_tm *tm)
-{
-       /* This will work from 1970-2099, 2100 is not a leap year */
-       static int mon_day[] = { 31, 29, 31, 30, 31, 30, 31,
-                                31, 30, 31, 30, 31 };
-       memset(tm, 0, sizeof(*tm));
-       tm->tm_sec  = tv->tv_sec % (24 * 60 * 60);
-       tm->tm_mday = tv->tv_sec / (24 * 60 * 60) +
-               (2 * 365 + 1); /* shift base from 1970 to 1968 */
-       tm->tm_min =  tm->tm_sec / 60 % 60;
-       tm->tm_hour = tm->tm_sec / 60 / 60;
-       tm->tm_sec =  tm->tm_sec % 60;
-       tm->tm_year = 68 + 4*(tm->tm_mday / (4*365+1));
-       tm->tm_mday %= (4*365+1);
-       mon_day[1] = 29;
-       while (tm->tm_mday >= mon_day[tm->tm_mon]) {
-               tm->tm_mday -= mon_day[tm->tm_mon];
-               if (++tm->tm_mon == 12) {
-                       tm->tm_mon = 0;
-                       ++tm->tm_year;
-                       mon_day[1] = 28;
-               }
-       }
-       ++tm->tm_mday;
-}
-
 /*
  * Most of this code has been lifted from kernel/timer.c::sys_sysinfo().
  * I cannot call that code directly from kdb, it has an unconditional
@@ -2515,10 +2506,10 @@ static void kdb_gmtime(struct timespec *tv, struct kdb_tm *tm)
  */
 static void kdb_sysinfo(struct sysinfo *val)
 {
-       struct timespec uptime;
-       ktime_get_ts(&uptime);
+       u64 uptime = ktime_get_mono_fast_ns();
+
        memset(val, 0, sizeof(*val));
-       val->uptime = uptime.tv_sec;
+       val->uptime = div_u64(uptime, NSEC_PER_SEC);
        val->loads[0] = avenrun[0];
        val->loads[1] = avenrun[1];
        val->loads[2] = avenrun[2];
@@ -2533,8 +2524,8 @@ static void kdb_sysinfo(struct sysinfo *val)
  */
 static int kdb_summary(int argc, const char **argv)
 {
-       struct timespec now;
-       struct kdb_tm tm;
+       time64_t now;
+       struct tm tm;
        struct sysinfo val;
 
        if (argc)
@@ -2548,9 +2539,9 @@ static int kdb_summary(int argc, const char **argv)
        kdb_printf("domainname %s\n", init_uts_ns.name.domainname);
        kdb_printf("ccversion  %s\n", __stringify(CCVERSION));
 
-       now = __current_kernel_time();
-       kdb_gmtime(&now, &tm);
-       kdb_printf("date       %04d-%02d-%02d %02d:%02d:%02d "
+       now = __ktime_get_real_seconds();
+       time64_to_tm(now, 0, &tm);
+       kdb_printf("date       %04ld-%02d-%02d %02d:%02d:%02d "
                   "tz_minuteswest %d\n",
                1900+tm.tm_year, tm.tm_mon+1, tm.tm_mday,
                tm.tm_hour, tm.tm_min, tm.tm_sec,