rk: printk: add pm_emit_log_char
[firefly-linux-kernel-4.4.55.git] / kernel / sys.c
index e4128b278f2375dc4e91c7244fbb4117b5230fea..01f195e9607323ac1595e429917b8617fdb727a6 100644 (file)
@@ -38,6 +38,8 @@
 #include <linux/fs_struct.h>
 #include <linux/gfp.h>
 #include <linux/syscore_ops.h>
+#include <linux/version.h>
+#include <linux/ctype.h>
 
 #include <linux/compat.h>
 #include <linux/syscalls.h>
 #include <linux/user_namespace.h>
 
 #include <linux/kmsg_dump.h>
+/* Move somewhere else to avoid recompiling? */
+#include <generated/utsrelease.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/unistd.h>
+/***************
+*       DEBUG
+****************/
+#define RESTART_DEBUG
+#ifdef RESTART_DEBUG
+#define restart_dbg(format, arg...) \
+       printk("RESTART_DEBUG : " format "\n" , ## arg)
+#else
+#define restart_dbg(format, arg...) do {} while (0)
+#endif
+
+
 
 #ifndef SET_UNALIGN_CTL
 # define SET_UNALIGN_CTL(a,b)  (-EINVAL)
@@ -329,7 +345,13 @@ void kernel_restart_prepare(char *cmd)
  */
 void kernel_restart(char *cmd)
 {
+       /*
+       *  debug trace
+       */
+       restart_dbg("%s->%d->cmd=%s",__FUNCTION__,__LINE__,cmd);
+       
        kernel_restart_prepare(cmd);
+       disable_nonboot_cpus();
        if (!cmd)
                printk(KERN_EMERG "Restarting system.\n");
        else
@@ -418,6 +440,11 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
        mutex_lock(&reboot_mutex);
        switch (cmd) {
        case LINUX_REBOOT_CMD_RESTART:
+               /*
+               *  debug trace
+               */
+               restart_dbg("%s->%d->cmd=%x",__FUNCTION__,__LINE__,cmd);
+               
                kernel_restart(NULL);
                break;
 
@@ -435,6 +462,11 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
                panic("cannot halt");
 
        case LINUX_REBOOT_CMD_POWER_OFF:
+               /*
+               *  debug trace
+               */
+               restart_dbg("%s->%d->cmd=%x",__FUNCTION__,__LINE__,cmd);
+               
                kernel_power_off();
                do_exit(0);
                break;
@@ -445,7 +477,11 @@ SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
                        break;
                }
                buffer[sizeof(buffer) - 1] = '\0';
-
+               /*
+               *  debug trace
+               */
+               restart_dbg("%s->%d->cmd=%x args=%s",__FUNCTION__,__LINE__,cmd,buffer);
+               
                kernel_restart(buffer);
                break;
 
@@ -1124,6 +1160,36 @@ DECLARE_RWSEM(uts_sem);
 #define override_architecture(name)    0
 #endif
 
+/*
+ * Work around broken programs that cannot handle "Linux 3.0".
+ * Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40
+ */
+static int override_release(char __user *release, size_t len)
+{
+       int ret = 0;
+
+       if (current->personality & UNAME26) {
+               const char *rest = UTS_RELEASE;
+               char buf[65] = { 0 };
+               int ndots = 0;
+               unsigned v;
+               size_t copy;
+
+               while (*rest) {
+                       if (*rest == '.' && ++ndots >= 3)
+                               break;
+                       if (!isdigit(*rest) && *rest != '.')
+                               break;
+                       rest++;
+               }
+               v = ((LINUX_VERSION_CODE >> 8) & 0xff) + 40;
+               copy = clamp_t(size_t, len, 1, sizeof(buf));
+               copy = scnprintf(buf, copy, "2.6.%u%s", v, rest);
+               ret = copy_to_user(release, buf, copy + 1);
+       }
+       return ret;
+}
+
 SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
 {
        int errno = 0;
@@ -1133,6 +1199,8 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
                errno = -EFAULT;
        up_read(&uts_sem);
 
+       if (!errno && override_release(name->release, sizeof(name->release)))
+               errno = -EFAULT;
        if (!errno && override_architecture(name))
                errno = -EFAULT;
        return errno;
@@ -1154,6 +1222,8 @@ SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
                error = -EFAULT;
        up_read(&uts_sem);
 
+       if (!error && override_release(name->release, sizeof(name->release)))
+               error = -EFAULT;
        if (!error && override_architecture(name))
                error = -EFAULT;
        return error;
@@ -1188,6 +1258,8 @@ SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
 
        if (!error && override_architecture(name))
                error = -EFAULT;
+       if (!error && override_release(name->release, sizeof(name->release)))
+               error = -EFAULT;
        return error ? -EFAULT : 0;
 }
 #endif