]> Git Repo - linux.git/commitdiff
Merge branch 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <[email protected]>
Wed, 16 Mar 2011 22:05:40 +0000 (15:05 -0700)
committerLinus Torvalds <[email protected]>
Wed, 16 Mar 2011 22:05:40 +0000 (15:05 -0700)
* 'driver-core-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (50 commits)
  printk: do not mangle valid userspace syslog prefixes
  efivars: Add Documentation
  efivars: Expose efivars functionality to external drivers.
  efivars: Parameterize operations.
  efivars: Split out variable registration
  efivars: parameterize efivars
  efivars: Make efivars bin_attributes dynamic
  efivars: move efivars globals into struct efivars
  drivers:misc: ti-st: fix debugging code
  kref: Fix typo in kref documentation
  UIO: add PRUSS UIO driver support
  Fix spelling mistakes in Documentation/zh_CN/SubmittingPatches
  firmware: Fix unaligned memory accesses in dmi-sysfs
  firmware: Add documentation for /sys/firmware/dmi
  firmware: Expose DMI type 15 System Event Log
  firmware: Break out system_event_log in dmi-sysfs
  firmware: Basic dmi-sysfs support
  firmware: Add DMI entry types to the headers
  Driver core: convert platform_{get,set}_drvdata to static inline functions
  Translate linux-2.6/Documentation/magic-number.txt into Chinese
  ...

1  2 
arch/x86/mm/init_64.c
init/Kconfig
kernel/printk.c

diff --combined arch/x86/mm/init_64.c
index a08a62cb136e409892701924732d8791bde4cff7,17e90d1f8c4d7de77b5b988298795df4cff75f04..0aa34669ed3f945400c46c737f63f5e01b6145dd
@@@ -51,6 -51,7 +51,7 @@@
  #include <asm/numa.h>
  #include <asm/cacheflush.h>
  #include <asm/init.h>
+ #include <asm/uv/uv.h>
  
  static int __init parse_direct_gbpages_off(char *arg)
  {
@@@ -105,18 -106,18 +106,18 @@@ void sync_global_pgds(unsigned long sta
  
        for (address = start; address <= end; address += PGDIR_SIZE) {
                const pgd_t *pgd_ref = pgd_offset_k(address);
 -              unsigned long flags;
                struct page *page;
  
                if (pgd_none(*pgd_ref))
                        continue;
  
 -              spin_lock_irqsave(&pgd_lock, flags);
 +              spin_lock(&pgd_lock);
                list_for_each_entry(page, &pgd_list, lru) {
                        pgd_t *pgd;
                        spinlock_t *pgt_lock;
  
                        pgd = (pgd_t *)page_address(page) + pgd_index(address);
 +                      /* the pgt_lock only for Xen */
                        pgt_lock = &pgd_page_get_mm(page)->page_table_lock;
                        spin_lock(pgt_lock);
  
  
                        spin_unlock(pgt_lock);
                }
 -              spin_unlock_irqrestore(&pgd_lock, flags);
 +              spin_unlock(&pgd_lock);
        }
  }
  
@@@ -314,7 -315,7 +315,7 @@@ void __init cleanup_highmap(void
  
  static __ref void *alloc_low_page(unsigned long *phys)
  {
 -      unsigned long pfn = e820_table_end++;
 +      unsigned long pfn = pgt_buf_end++;
        void *adr;
  
        if (after_bootmem) {
                return adr;
        }
  
 -      if (pfn >= e820_table_top)
 +      if (pfn >= pgt_buf_top)
                panic("alloc_low_page: ran out of memory");
  
        adr = early_memremap(pfn * PAGE_SIZE, PAGE_SIZE);
        return adr;
  }
  
 +static __ref void *map_low_page(void *virt)
 +{
 +      void *adr;
 +      unsigned long phys, left;
 +
 +      if (after_bootmem)
 +              return virt;
 +
 +      phys = __pa(virt);
 +      left = phys & (PAGE_SIZE - 1);
 +      adr = early_memremap(phys & PAGE_MASK, PAGE_SIZE);
 +      adr = (void *)(((unsigned long)adr) | left);
 +
 +      return adr;
 +}
 +
  static __ref void unmap_low_page(void *adr)
  {
        if (after_bootmem)
                return;
  
 -      early_iounmap(adr, PAGE_SIZE);
 +      early_iounmap((void *)((unsigned long)adr & PAGE_MASK), PAGE_SIZE);
  }
  
  static unsigned long __meminit
@@@ -401,6 -386,15 +402,6 @@@ phys_pte_init(pte_t *pte_page, unsigne
        return last_map_addr;
  }
  
 -static unsigned long __meminit
 -phys_pte_update(pmd_t *pmd, unsigned long address, unsigned long end,
 -              pgprot_t prot)
 -{
 -      pte_t *pte = (pte_t *)pmd_page_vaddr(*pmd);
 -
 -      return phys_pte_init(pte, address, end, prot);
 -}
 -
  static unsigned long __meminit
  phys_pmd_init(pmd_t *pmd_page, unsigned long address, unsigned long end,
              unsigned long page_size_mask, pgprot_t prot)
                if (pmd_val(*pmd)) {
                        if (!pmd_large(*pmd)) {
                                spin_lock(&init_mm.page_table_lock);
 -                              last_map_addr = phys_pte_update(pmd, address,
 +                              pte = map_low_page((pte_t *)pmd_page_vaddr(*pmd));
 +                              last_map_addr = phys_pte_init(pte, address,
                                                                end, prot);
 +                              unmap_low_page(pte);
                                spin_unlock(&init_mm.page_table_lock);
                                continue;
                        }
        return last_map_addr;
  }
  
 -static unsigned long __meminit
 -phys_pmd_update(pud_t *pud, unsigned long address, unsigned long end,
 -              unsigned long page_size_mask, pgprot_t prot)
 -{
 -      pmd_t *pmd = pmd_offset(pud, 0);
 -      unsigned long last_map_addr;
 -
 -      last_map_addr = phys_pmd_init(pmd, address, end, page_size_mask, prot);
 -      __flush_tlb_all();
 -      return last_map_addr;
 -}
 -
  static unsigned long __meminit
  phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end,
                         unsigned long page_size_mask)
  
                if (pud_val(*pud)) {
                        if (!pud_large(*pud)) {
 -                              last_map_addr = phys_pmd_update(pud, addr, end,
 +                              pmd = map_low_page(pmd_offset(pud, 0));
 +                              last_map_addr = phys_pmd_init(pmd, addr, end,
                                                         page_size_mask, prot);
 +                              unmap_low_page(pmd);
 +                              __flush_tlb_all();
                                continue;
                        }
                        /*
        return last_map_addr;
  }
  
 -static unsigned long __meminit
 -phys_pud_update(pgd_t *pgd, unsigned long addr, unsigned long end,
 -               unsigned long page_size_mask)
 -{
 -      pud_t *pud;
 -
 -      pud = (pud_t *)pgd_page_vaddr(*pgd);
 -
 -      return phys_pud_init(pud, addr, end, page_size_mask);
 -}
 -
  unsigned long __meminit
  kernel_physical_mapping_init(unsigned long start,
                             unsigned long end,
                        next = end;
  
                if (pgd_val(*pgd)) {
 -                      last_map_addr = phys_pud_update(pgd, __pa(start),
 +                      pud = map_low_page((pud_t *)pgd_page_vaddr(*pgd));
 +                      last_map_addr = phys_pud_init(pud, __pa(start),
                                                 __pa(end), page_size_mask);
 +                      unmap_low_page(pud);
                        continue;
                }
  
  }
  
  #ifndef CONFIG_NUMA
 -void __init initmem_init(unsigned long start_pfn, unsigned long end_pfn,
 -                              int acpi, int k8)
 +void __init initmem_init(void)
  {
 -      memblock_x86_register_active_regions(0, start_pfn, end_pfn);
 +      memblock_x86_register_active_regions(0, 0, max_pfn);
  }
  #endif
  
@@@ -898,6 -909,19 +899,19 @@@ const char *arch_vma_name(struct vm_are
        return NULL;
  }
  
+ #ifdef CONFIG_X86_UV
+ #define MIN_MEMORY_BLOCK_SIZE   (1 << SECTION_SIZE_BITS)
+ unsigned long memory_block_size_bytes(void)
+ {
+       if (is_uv_system()) {
+               printk(KERN_INFO "UV: memory block size 2GB\n");
+               return 2UL * 1024 * 1024 * 1024;
+       }
+       return MIN_MEMORY_BLOCK_SIZE;
+ }
+ #endif
  #ifdef CONFIG_SPARSEMEM_VMEMMAP
  /*
   * Initialise the sparsemem vmemmap using huge-pages at the PMD level.
diff --combined init/Kconfig
index 5721d27af626adb6974c92bd1065adb27fa5748c,e72fd101039e18a8a3dbd342ee2ad98ca7d73dea..6f49ceb2571007d7e062ed07ca679f4edbb8012d
@@@ -287,18 -287,6 +287,18 @@@ config BSD_PROCESS_ACCT_V
          for processing it. A preliminary version of these tools is available
          at <http://www.gnu.org/software/acct/>.
  
 +config FHANDLE
 +      bool "open by fhandle syscalls"
 +      select EXPORTFS
 +      help
 +        If you say Y here, a user level program will be able to map
 +        file names to handle and then later use the handle for
 +        different file system operations. This is useful in implementing
 +        userspace file servers, which now track files using handles instead
 +        of names. The handle would remain the same even if file names
 +        get renamed. Enables open_by_handle_at(2) and name_to_handle_at(2)
 +        syscalls.
 +
  config TASKSTATS
        bool "Export task/process statistics through netlink (EXPERIMENTAL)"
        depends on NET
@@@ -695,16 -683,6 +695,16 @@@ config CGROUP_MEM_RES_CTLR_SWAP_ENABLE
          select this option (if, for some reason, they need to disable it
          then noswapaccount does the trick).
  
 +config CGROUP_PERF
 +      bool "Enable perf_event per-cpu per-container group (cgroup) monitoring"
 +      depends on PERF_EVENTS && CGROUPS
 +      help
 +        This option extends the per-cpu mode to restrict monitoring to
 +        threads which belong to the cgroup specified and run on the
 +        designated cpu.
 +
 +        Say N if unsure.
 +
  menuconfig CGROUP_SCHED
        bool "Group CPU scheduler"
        depends on EXPERIMENTAL
@@@ -836,7 -814,7 +836,7 @@@ config MM_OWNE
        bool
  
  config SYSFS_DEPRECATED
-       bool "enable deprecated sysfs features to support old userspace tools"
+       bool "Enable deprecated sysfs features to support old userspace tools"
        depends on SYSFS
        default n
        help
          need to say Y here.
  
  config SYSFS_DEPRECATED_V2
-       bool "enabled deprecated sysfs features by default"
+       bool "Enable deprecated sysfs features by default"
        default n
        depends on SYSFS
        depends on SYSFS_DEPRECATED
diff --combined kernel/printk.c
index 36231525e22fd73e719dd62a7c3b211bcf24f3e0,5e3d042e7001ab3888ce392ac69cba0ab7d1a522..33284adb21895b7bee8fa74b160f86d7f1458d52
@@@ -262,47 -262,25 +262,47 @@@ int dmesg_restrict = 1
  int dmesg_restrict;
  #endif
  
 +static int syslog_action_restricted(int type)
 +{
 +      if (dmesg_restrict)
 +              return 1;
 +      /* Unless restricted, we allow "read all" and "get buffer size" for everybody */
 +      return type != SYSLOG_ACTION_READ_ALL && type != SYSLOG_ACTION_SIZE_BUFFER;
 +}
 +
 +static int check_syslog_permissions(int type, bool from_file)
 +{
 +      /*
 +       * If this is from /proc/kmsg and we've already opened it, then we've
 +       * already done the capabilities checks at open time.
 +       */
 +      if (from_file && type != SYSLOG_ACTION_OPEN)
 +              return 0;
 +
 +      if (syslog_action_restricted(type)) {
 +              if (capable(CAP_SYSLOG))
 +                      return 0;
 +              /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */
 +              if (capable(CAP_SYS_ADMIN)) {
 +                      WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN "
 +                               "but no CAP_SYSLOG (deprecated).\n");
 +                      return 0;
 +              }
 +              return -EPERM;
 +      }
 +      return 0;
 +}
 +
  int do_syslog(int type, char __user *buf, int len, bool from_file)
  {
        unsigned i, j, limit, count;
        int do_clear = 0;
        char c;
 -      int error = 0;
 +      int error;
  
 -      /*
 -       * If this is from /proc/kmsg we only do the capabilities checks
 -       * at open time.
 -       */
 -      if (type == SYSLOG_ACTION_OPEN || !from_file) {
 -              if (dmesg_restrict && !capable(CAP_SYSLOG))
 -                      goto warn; /* switch to return -EPERM after 2.6.39 */
 -              if ((type != SYSLOG_ACTION_READ_ALL &&
 -                   type != SYSLOG_ACTION_SIZE_BUFFER) &&
 -                  !capable(CAP_SYSLOG))
 -                      goto warn; /* switch to return -EPERM after 2.6.39 */
 -      }
 +      error = check_syslog_permissions(type, from_file);
 +      if (error)
 +              goto out;
  
        error = security_syslog(type);
        if (error)
        }
  out:
        return error;
 -warn:
 -      /* remove after 2.6.39 */
 -      if (capable(CAP_SYS_ADMIN))
 -              WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN "
 -                "but no CAP_SYSLOG (deprecated and denied).\n");
 -      return -EPERM;
  }
  
  SYSCALL_DEFINE3(syslog, int, type, char __user *, buf, int, len)
@@@ -514,6 -498,71 +514,71 @@@ static void _call_console_drivers(unsig
        }
  }
  
+ /*
+  * Parse the syslog header <[0-9]*>. The decimal value represents 32bit, the
+  * lower 3 bit are the log level, the rest are the log facility. In case
+  * userspace passes usual userspace syslog messages to /dev/kmsg or
+  * /dev/ttyprintk, the log prefix might contain the facility. Printk needs
+  * to extract the correct log level for in-kernel processing, and not mangle
+  * the original value.
+  *
+  * If a prefix is found, the length of the prefix is returned. If 'level' is
+  * passed, it will be filled in with the log level without a possible facility
+  * value. If 'special' is passed, the special printk prefix chars are accepted
+  * and returned. If no valid header is found, 0 is returned and the passed
+  * variables are not touched.
+  */
+ static size_t log_prefix(const char *p, unsigned int *level, char *special)
+ {
+       unsigned int lev = 0;
+       char sp = '\0';
+       size_t len;
+       if (p[0] != '<' || !p[1])
+               return 0;
+       if (p[2] == '>') {
+               /* usual single digit level number or special char */
+               switch (p[1]) {
+               case '0' ... '7':
+                       lev = p[1] - '0';
+                       break;
+               case 'c': /* KERN_CONT */
+               case 'd': /* KERN_DEFAULT */
+                       sp = p[1];
+                       break;
+               default:
+                       return 0;
+               }
+               len = 3;
+       } else {
+               /* multi digit including the level and facility number */
+               char *endp = NULL;
+               if (p[1] < '0' && p[1] > '9')
+                       return 0;
+               lev = (simple_strtoul(&p[1], &endp, 10) & 7);
+               if (endp == NULL || endp[0] != '>')
+                       return 0;
+               len = (endp + 1) - p;
+       }
+       /* do not accept special char if not asked for */
+       if (sp && !special)
+               return 0;
+       if (special) {
+               *special = sp;
+               /* return special char, do not touch level */
+               if (sp)
+                       return len;
+       }
+       if (level)
+               *level = lev;
+       return len;
+ }
  /*
   * Call the console drivers, asking them to write out
   * log_buf[start] to log_buf[end - 1].
@@@ -529,13 -578,9 +594,9 @@@ static void call_console_drivers(unsign
        cur_index = start;
        start_print = start;
        while (cur_index != end) {
-               if (msg_level < 0 && ((end - cur_index) > 2) &&
-                               LOG_BUF(cur_index + 0) == '<' &&
-                               LOG_BUF(cur_index + 1) >= '0' &&
-                               LOG_BUF(cur_index + 1) <= '7' &&
-                               LOG_BUF(cur_index + 2) == '>') {
-                       msg_level = LOG_BUF(cur_index + 1) - '0';
-                       cur_index += 3;
+               if (msg_level < 0 && ((end - cur_index) > 2)) {
+                       /* strip log prefix */
+                       cur_index += log_prefix(&LOG_BUF(cur_index), &msg_level, NULL);
                        start_print = cur_index;
                }
                while (cur_index != end) {
@@@ -733,6 -778,8 +794,8 @@@ asmlinkage int vprintk(const char *fmt
        unsigned long flags;
        int this_cpu;
        char *p;
+       size_t plen;
+       char special;
  
        boot_delay_msec();
        printk_delay();
        printed_len += vscnprintf(printk_buf + printed_len,
                                  sizeof(printk_buf) - printed_len, fmt, args);
  
        p = printk_buf;
  
-       /* Do we have a loglevel in the string? */
-       if (p[0] == '<') {
-               unsigned char c = p[1];
-               if (c && p[2] == '>') {
-                       switch (c) {
-                       case '0' ... '7': /* loglevel */
-                               current_log_level = c - '0';
-                       /* Fallthrough - make sure we're on a new line */
-                       case 'd': /* KERN_DEFAULT */
-                               if (!new_text_line) {
-                                       emit_log_char('\n');
-                                       new_text_line = 1;
-                               }
-                       /* Fallthrough - skip the loglevel */
-                       case 'c': /* KERN_CONT */
-                               p += 3;
-                               break;
+       /* Read log level and handle special printk prefix */
+       plen = log_prefix(p, &current_log_level, &special);
+       if (plen) {
+               p += plen;
+               switch (special) {
+               case 'c': /* Strip <c> KERN_CONT, continue line */
+                       plen = 0;
+                       break;
+               case 'd': /* Strip <d> KERN_DEFAULT, start new line */
+                       plen = 0;
+               default:
+                       if (!new_text_line) {
+                               emit_log_char('\n');
+                               new_text_line = 1;
                        }
                }
        }
  
        /*
-        * Copy the output into log_buf.  If the caller didn't provide
-        * appropriate log level tags, we insert them here
+        * Copy the output into log_buf. If the caller didn't provide
+        * the appropriate log prefix, we insert them here
         */
-       for ( ; *p; p++) {
+       for (; *p; p++) {
                if (new_text_line) {
-                       /* Always output the token */
-                       emit_log_char('<');
-                       emit_log_char(current_log_level + '0');
-                       emit_log_char('>');
-                       printed_len += 3;
                        new_text_line = 0;
  
+                       if (plen) {
+                               /* Copy original log prefix */
+                               int i;
+                               for (i = 0; i < plen; i++)
+                                       emit_log_char(printk_buf[i]);
+                               printed_len += plen;
+                       } else {
+                               /* Add log prefix */
+                               emit_log_char('<');
+                               emit_log_char(current_log_level + '0');
+                               emit_log_char('>');
+                               printed_len += 3;
+                       }
                        if (printk_time) {
-                               /* Follow the token with the time */
+                               /* Add the current time stamp */
                                char tbuf[50], *tp;
                                unsigned tlen;
                                unsigned long long t;
This page took 0.108351 seconds and 4 git commands to generate.