[haiku-commits] haiku: hrev46518 - src/system/kernel/debug src/system/kernel/vm headers/private/kernel src/system/boot/loader src/system/kernel/arch/x86

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 10 Dec 2013 19:14:41 +0100 (CET)

hrev46518 adds 7 changesets to branch 'master'
old head: 84ec24f2ff4aacf10ffc2a7f59ae7788c00f49f5
new head: c259766f94e7cfbe9318eda438d89f62a5099949
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=c259766+%5E84ec24f

----------------------------------------------------------------------------

7a1e706: safemode.h: Update coding style

9bdb5e0: kernel safemode: Add functions to get options early
  
  Add get_safemode_option_early() and get_safemode_boolean_early() to get
  safemode options before the kernel heap has been initialized. They use a
  simplified parser.

647b768: x86: Disable PAE, if 4 GB memory limit safemode is set

fc7801b: boot loader: apply_boot_settings(): Replace string literal

a3fe978: boot loader: Always show 4 GB memory limit safemode option
  
  On x86 we mainly want to disable PAE, which is now also used with less
  memory as long as NX support is available. Ideally we'd check this
  condition as well and only add the menu item, if the kernel would
  enable PAE.

5d3978d: KDL "mapping" command: Fix argument check
  
  It wasn't possible to actually specify the second argument (team ID).

c259766: KDL "mapping" command: Allow specifying a thread ID
  
  ... instead of only a team ID.

                                    [ Ingo Weinhold <ingo_weinhold@xxxxxx> ]

----------------------------------------------------------------------------

6 files changed, 265 insertions(+), 66 deletions(-)
headers/private/kernel/safemode.h                |  22 +-
src/system/boot/loader/load_driver_settings.cpp  |   4 +-
src/system/boot/loader/menu.cpp                  |   8 +-
.../kernel/arch/x86/arch_vm_translation_map.cpp  |  12 +-
src/system/kernel/debug/safemode_settings.cpp    | 228 ++++++++++++++++---
src/system/kernel/vm/vm.cpp                      |  57 +++--

############################################################################

Commit:      7a1e706df778d7cc0d5a10a20f8397660c274e2a
URL:         http://cgit.haiku-os.org/haiku/commit/?id=7a1e706
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue Dec 10 16:07:20 2013 UTC

safemode.h: Update coding style

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/safemode.h 
b/headers/private/kernel/safemode.h
index c61ba0d..308edfa 100644
--- a/headers/private/kernel/safemode.h
+++ b/headers/private/kernel/safemode.h
@@ -5,6 +5,7 @@
 #ifndef _KERNEL_SAFEMODE_H
 #define _KERNEL_SAFEMODE_H
 
+
 #include <driver_settings.h>
 
 #include <safemode_defs.h>
@@ -14,12 +15,17 @@
 extern "C" {
 #endif
 
-status_t get_safemode_option(const char *parameter, char *buffer, size_t 
*_bufferSize);
-bool get_safemode_boolean(const char *parameter, bool defaultValue);
-status_t _user_get_safemode_option(const char *parameter, char *buffer, size_t 
*_bufferSize);
+
+status_t       get_safemode_option(const char* parameter, char* buffer,
+                               size_t* _bufferSize);
+bool           get_safemode_boolean(const char* parameter, bool defaultValue);
+status_t       _user_get_safemode_option(const char* parameter, char* buffer,
+                               size_t* _bufferSize);
+
 
 #ifdef __cplusplus
 }
 #endif
 
+
 #endif /* _KERNEL_SAFEMODE_H */

############################################################################

Commit:      9bdb5e0a928dcaa7d44f3111cb44e7a3a6d9bae2
URL:         http://cgit.haiku-os.org/haiku/commit/?id=9bdb5e0
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue Dec 10 18:05:47 2013 UTC

kernel safemode: Add functions to get options early

Add get_safemode_option_early() and get_safemode_boolean_early() to get
safemode options before the kernel heap has been initialized. They use a
simplified parser.

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/safemode.h 
b/headers/private/kernel/safemode.h
index 308edfa..bcf5751 100644
--- a/headers/private/kernel/safemode.h
+++ b/headers/private/kernel/safemode.h
@@ -11,6 +11,9 @@
 #include <safemode_defs.h>
 
 
+struct kernel_args;
+
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -19,6 +22,13 @@ extern "C" {
 status_t       get_safemode_option(const char* parameter, char* buffer,
                                size_t* _bufferSize);
 bool           get_safemode_boolean(const char* parameter, bool defaultValue);
+
+// before driver_settings_init() has been called (limited parsing support)
+status_t       get_safemode_option_early(kernel_args* args, const char* 
parameter,
+                               char* buffer, size_t* _bufferSize);
+bool           get_safemode_boolean_early(kernel_args* args, const char* 
parameter,
+                               bool defaultValue);
+
 status_t       _user_get_safemode_option(const char* parameter, char* buffer,
                                size_t* _bufferSize);
 
diff --git a/src/system/kernel/debug/safemode_settings.cpp 
b/src/system/kernel/debug/safemode_settings.cpp
index 2cb9950..61334ae 100644
--- a/src/system/kernel/debug/safemode_settings.cpp
+++ b/src/system/kernel/debug/safemode_settings.cpp
@@ -4,59 +4,194 @@
  */
 
 
+#include <safemode.h>
+
+#include <ctype.h>
+#include <string.h>
+
+#include <algorithm>
+
 #include <KernelExport.h>
 
-#include <safemode.h>
+#include <boot/kernel_args.h>
 #include <kernel.h>
 #include <syscalls.h>
 
-#include <string.h>
 
+#ifndef _BOOT_MODE
 
-extern "C" status_t
-get_safemode_option(const char* parameter, char* buffer, size_t* _bufferSize)
+
+static status_t
+get_option_from_kernel_args(kernel_args* args, const char* settingsName,
+       const char* parameter, size_t parameterLength, char* buffer,
+       size_t* _bufferSize)
 {
-       status_t status = B_ENTRY_NOT_FOUND;
+       // find the settings in the kernel args
+       const char* settings = NULL;
+       for (driver_settings_file* file = args->driver_settings;
+                       file != NULL; file = file->next) {
+               if (strcmp(settingsName, file->name) == 0) {
+                       settings = file->buffer;
+                       break;
+               }
+       }
+
+       if (settings == NULL)
+               return B_ENTRY_NOT_FOUND;
+
+       // Unfortunately we can't just use parse_driver_settings_string(), since
+       // we might not have a working heap yet. So we do very limited parsing
+       // ourselves.
+       const char* settingsEnd = settings + strlen(settings);
+       int32 parameterLevel = 0;
+
+       while (*settings != '\0') {
+               // find end of line
+               const char* lineEnd = strchr(settings, '\n');
+               const char* nextLine;
+               if (lineEnd != NULL)
+                       nextLine = lineEnd + 1;
+               else
+                       nextLine = lineEnd = settingsEnd;
+
+               // ignore any trailing comments
+               lineEnd = std::find(settings, lineEnd, '#');
+
+               const char* nameStart = NULL;
+               const char* nameEnd = NULL;
+               const char* valueStart = NULL;
+               const char* valueEnd = NULL;
+               const char** elementEnd = NULL;
+               bool sawSeparator = true;
+
+               for (; settings < lineEnd; settings++) {
+                       switch (*settings) {
+                               case '{':
+                                       parameterLevel++;
+                                       sawSeparator = true;
+                                       break;
+
+                               case '}':
+                                       parameterLevel--;
+                                       sawSeparator = true;
+                                       break;
+
+                               case ';':
+                                       // TODO: That's not correct. There 
should be another loop.
+                                       sawSeparator = true;
+                                       break;
 
-       void* handle = load_driver_settings(B_SAFEMODE_DRIVER_SETTINGS);
-       if (handle != NULL) {
-               status = B_NAME_NOT_FOUND;
+                               default:
+                                       if (parameterLevel != 0)
+                                               break;
 
-               const char* value = get_driver_parameter(handle, parameter, 
NULL, NULL);
-               if (value != NULL) {
-                       *_bufferSize = strlcpy(buffer, value, *_bufferSize);
-                       status = B_OK;
+                                       if (isspace(*settings)) {
+                                               sawSeparator = true;
+                                               break;
+                                       }
+
+                                       if (!sawSeparator)
+                                               break;
+
+                                       sawSeparator = false;
+
+                                       if (nameStart == NULL) {
+                                               nameStart = settings;
+                                               elementEnd = &nameEnd;
+                                       } else if (valueStart == NULL) {
+                                               valueStart = settings;
+                                               elementEnd = &valueEnd;
+                                       }
+                                       break;
+                       }
+
+                       if (sawSeparator && elementEnd != NULL) {
+                               *elementEnd = settings;
+                               elementEnd = NULL;
+                       }
                }
 
-               unload_driver_settings(handle);
-       }
+               if (elementEnd != NULL)
+                       *elementEnd = settings;
 
-       if (status != B_OK) {
-               // Try kernel settings file as a fall back
-               handle = load_driver_settings("kernel");
-               if (handle != NULL) {
-                       const char* value = get_driver_parameter(handle, 
parameter, NULL,
-                               NULL);
-                       if (value != NULL) {
-                               *_bufferSize = strlcpy(buffer, value, 
*_bufferSize);
-                               status = B_OK;
+               if (nameStart != NULL && size_t(nameEnd - nameStart) == 
parameterLength
+                       && strncmp(parameter, nameStart, parameterLength) == 0) 
{
+                       if (valueStart == NULL)
+                               return B_NAME_NOT_FOUND;
+
+                       size_t length = valueEnd - valueStart;
+                       if (*_bufferSize > 0) {
+                               size_t toCopy = std::min(length, *_bufferSize - 
1);
+                               memcpy(buffer, valueStart, toCopy);
+                               buffer[toCopy] = '\0';
                        }
 
-                       unload_driver_settings(handle);
+                       *_bufferSize = length;
+                       return B_OK;
                }
+
+               settings = nextLine;
        }
 
+       return B_NAME_NOT_FOUND;
+}
+
+
+#endif // !_BOOT_MODE
+
+
+static status_t
+get_option(kernel_args* args, const char* settingsName, const char* parameter,
+       size_t parameterLength, char* buffer, size_t* _bufferSize)
+{
+#ifndef _BOOT_MODE
+       if (args != NULL) {
+               return get_option_from_kernel_args(args, settingsName, 
parameter,
+                       parameterLength, buffer, _bufferSize);
+       }
+#endif
+
+       void* handle = load_driver_settings(settingsName);
+       if (handle == NULL)
+               return B_ENTRY_NOT_FOUND;
+
+       status_t status = B_NAME_NOT_FOUND;
+
+       const char* value = get_driver_parameter(handle, parameter, NULL, NULL);
+       if (value != NULL) {
+               *_bufferSize = strlcpy(buffer, value, *_bufferSize);
+               status = B_OK;
+       }
+
+       unload_driver_settings(handle);
        return status;
 }
 
 
-extern "C" bool
-get_safemode_boolean(const char* parameter, bool defaultValue)
+static status_t
+get_option(kernel_args* args, const char* parameter, char* buffer,
+       size_t* _bufferSize)
+{
+       size_t parameterLength = strlen(parameter);
+       status_t status = get_option(args, B_SAFEMODE_DRIVER_SETTINGS, 
parameter,
+               parameterLength, buffer, _bufferSize);
+       if (status != B_OK) {
+               // Try kernel settings file as a fall back
+               status = get_option(args, "kernel", parameter, parameterLength, 
buffer,
+                       _bufferSize);
+       }
+
+       return status;
+}
+
+
+static bool
+get_boolean(kernel_args* args, const char* parameter, bool defaultValue)
 {
        char value[16];
        size_t length = sizeof(value);
 
-       if (get_safemode_option(parameter, value, &length) != B_OK)
+       if (get_option(args, parameter, value, &length) != B_OK)
                return defaultValue;
 
        return !strcasecmp(value, "on") || !strcasecmp(value, "true")
@@ -65,6 +200,45 @@ get_safemode_boolean(const char* parameter, bool 
defaultValue)
 }
 
 
+// #pragma mark -
+
+
+status_t
+get_safemode_option(const char* parameter, char* buffer, size_t* _bufferSize)
+{
+       return get_option(NULL, parameter, buffer, _bufferSize);
+}
+
+
+bool
+get_safemode_boolean(const char* parameter, bool defaultValue)
+{
+       return get_boolean(NULL, parameter, defaultValue);
+}
+
+
+#ifndef _BOOT_MODE
+
+
+status_t
+get_safemode_option_early(kernel_args* args, const char* parameter,
+       char* buffer, size_t* _bufferSize)
+{
+       return get_option(args, parameter, buffer, _bufferSize);
+}
+
+
+bool
+get_safemode_boolean_early(kernel_args* args, const char* parameter,
+       bool defaultValue)
+{
+       return get_boolean(args, parameter, defaultValue);
+}
+
+
+#endif // _BOOT_MODE
+
+
 //     #pragma mark - syscalls
 
 

############################################################################

Commit:      647b768f543c4d275390856edcc733327d7ae30c
URL:         http://cgit.haiku-os.org/haiku/commit/?id=647b768
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue Dec 10 18:07:01 2013 UTC

x86: Disable PAE, if 4 GB memory limit safemode is set

----------------------------------------------------------------------------

diff --git a/src/system/kernel/arch/x86/arch_vm_translation_map.cpp 
b/src/system/kernel/arch/x86/arch_vm_translation_map.cpp
index c9ac7a4..728dbd8 100644
--- a/src/system/kernel/arch/x86/arch_vm_translation_map.cpp
+++ b/src/system/kernel/arch/x86/arch_vm_translation_map.cpp
@@ -11,6 +11,7 @@
 #include <arch/vm_translation_map.h>
 
 #include <boot/kernel_args.h>
+#include <safemode.h>
 
 #ifdef __x86_64__
 #      include "paging/64bit/X86PagingMethod64Bit.h"
@@ -99,12 +100,17 @@ arch_vm_translation_map_init(kernel_args *args,
                }
        }
 
-       if (paeAvailable && paeNeeded) {
+       bool paeDisabled = get_safemode_boolean_early(args,
+               B_SAFEMODE_4_GB_MEMORY_LIMIT, false);
+
+       if (paeAvailable && paeNeeded && !paeDisabled) {
                dprintf("using PAE paging\n");
                gX86PagingMethod = new(&sPagingMethodBuffer) X86PagingMethodPAE;
        } else {
-               dprintf("using 32 bit paging (PAE not %s)\n",
-                       paeNeeded ? "available" : "needed");
+               dprintf("using 32 bit paging (PAE %s)\n",
+                       paeNeeded
+                               ? "not available"
+                               : (paeDisabled ? "disabled" : "not needed"));
                gX86PagingMethod = new(&sPagingMethodBuffer) 
X86PagingMethod32Bit;
        }
 #else

############################################################################

Commit:      fc7801bc6fb1df1acb384f1bf15cdc1638037e73
URL:         http://cgit.haiku-os.org/haiku/commit/?id=fc7801b
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue Dec 10 18:08:07 2013 UTC

boot loader: apply_boot_settings(): Replace string literal

----------------------------------------------------------------------------

diff --git a/src/system/boot/loader/load_driver_settings.cpp 
b/src/system/boot/loader/load_driver_settings.cpp
index 65aca1d..5eabfd4 100644
--- a/src/system/boot/loader/load_driver_settings.cpp
+++ b/src/system/boot/loader/load_driver_settings.cpp
@@ -67,8 +67,8 @@ apply_boot_settings(void* kernelSettings, void* 
safemodeSettings)
 {
 #if B_HAIKU_PHYSICAL_BITS > 32
        if ((kernelSettings != NULL
-                       && get_driver_boolean_parameter(kernelSettings, 
"4gb_memory_limit",
-                               false, false))
+                       && get_driver_boolean_parameter(kernelSettings,
+                               B_SAFEMODE_4_GB_MEMORY_LIMIT, false, false))
                || (safemodeSettings != NULL
                        && get_driver_boolean_parameter(safemodeSettings,
                                B_SAFEMODE_4_GB_MEMORY_LIMIT, false, false))) {

############################################################################

Commit:      a3fe978f8ab957ea216b6d50982c7da2b70abea2
URL:         http://cgit.haiku-os.org/haiku/commit/?id=a3fe978
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue Dec 10 18:12:16 2013 UTC

boot loader: Always show 4 GB memory limit safemode option

On x86 we mainly want to disable PAE, which is now also used with less
memory as long as NX support is available. Ideally we'd check this
condition as well and only add the menu item, if the kernel would
enable PAE.

----------------------------------------------------------------------------

diff --git a/src/system/boot/loader/menu.cpp b/src/system/boot/loader/menu.cpp
index 400b8e4..8f35f19 100644
--- a/src/system/boot/loader/menu.cpp
+++ b/src/system/boot/loader/menu.cpp
@@ -1135,8 +1135,12 @@ add_safe_mode_menu()
                }
        }
 
-       // ... add the menu, if so
-       if (hasMemoryBeyond4GB) {
+       bool needs64BitPaging = true;
+               // TODO: Determine whether 64 bit paging (i.e. PAE for x86) is 
needed
+               // for other reasons (NX support).
+
+       // ... add the menu item, if so
+       if (hasMemoryBeyond4GB || needs64BitPaging) {
                safeMenu->AddItem(
                        item = new(nothrow) MenuItem("Ignore memory beyond 4 
GiB"));
                item->SetData(B_SAFEMODE_4_GB_MEMORY_LIMIT);

############################################################################

Commit:      5d3978dbe7351942a45066d3f0b70ce8973144b4
URL:         http://cgit.haiku-os.org/haiku/commit/?id=5d3978d
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue Dec 10 18:13:08 2013 UTC

KDL "mapping" command: Fix argument check

It wasn't possible to actually specify the second argument (team ID).

----------------------------------------------------------------------------

diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp
index 0d2dea1..f342e19 100644
--- a/src/system/kernel/vm/vm.cpp
+++ b/src/system/kernel/vm/vm.cpp
@@ -3432,7 +3432,7 @@ dump_mapping_info(int argc, char** argv)
 
        // We need at least one argument, the address. Optionally a team ID can 
be
        // specified.
-       if (argi >= argc || argi + 1 < argc) {
+       if (argi >= argc || argi + 2 < argc) {
                print_debugger_command_usage(argv[0]);
                return 0;
        }

############################################################################

Revision:    hrev46518
Commit:      c259766f94e7cfbe9318eda438d89f62a5099949
URL:         http://cgit.haiku-os.org/haiku/commit/?id=c259766
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Tue Dec 10 18:13:56 2013 UTC

KDL "mapping" command: Allow specifying a thread ID

... instead of only a team ID.

----------------------------------------------------------------------------

diff --git a/src/system/kernel/vm/vm.cpp b/src/system/kernel/vm/vm.cpp
index f342e19..d4a01cc 100644
--- a/src/system/kernel/vm/vm.cpp
+++ b/src/system/kernel/vm/vm.cpp
@@ -3430,7 +3430,7 @@ dump_mapping_info(int argc, char** argv)
                }
        }
 
-       // We need at least one argument, the address. Optionally a team ID can 
be
+       // We need at least one argument, the address. Optionally a thread ID 
can be
        // specified.
        if (argi >= argc || argi + 2 < argc) {
                print_debugger_command_usage(argv[0]);
@@ -3441,11 +3441,19 @@ dump_mapping_info(int argc, char** argv)
        if (!evaluate_debug_expression(argv[argi++], &addressValue, false))
                return 0;
 
-       uint64 teamID = B_CURRENT_TEAM;
-       bool teamSpecified = argi < argc;
-       if (teamSpecified) {
-               if (!evaluate_debug_expression(argv[argi++], &teamID, false))
+       Team* team = NULL;
+       if (argi < argc) {
+               uint64 threadID = -1;
+               if (!evaluate_debug_expression(argv[argi++], &threadID, false))
                        return 0;
+
+               Thread* thread = Thread::GetDebug(threadID);
+               if (thread == NULL) {
+                       kprintf("Invalid thread/team ID \"%s\"\n", argv[argi - 
1]);
+                       return 0;
+               }
+
+               team = thread->team;
        }
 
        if (reverseLookup) {
@@ -3488,20 +3496,9 @@ dump_mapping_info(int argc, char** argv)
                        VMAddressSpace* fAddressSpace;
                } callback;
 
-               if (teamSpecified) {
+               if (team != NULL) {
                        // team specified -- get its address space
-                       VMAddressSpace* addressSpace;
-                       if (teamID == B_CURRENT_TEAM) {
-                               Thread* thread = debug_get_debugged_thread();
-                               if (thread == NULL || thread->team == NULL) {
-                                       kprintf("Failed to get team!\n");
-                                       return 0;
-                               }
-
-                               addressSpace = thread->team->address_space;
-                       } else
-                               addressSpace = VMAddressSpace::DebugGet(teamID);
-
+                       VMAddressSpace* addressSpace = team->address_space;
                        if (addressSpace == NULL) {
                                kprintf("Failed to get address space!\n");
                                return 0;
@@ -3527,7 +3524,9 @@ dump_mapping_info(int argc, char** argv)
                VMAddressSpace* addressSpace;
                if (IS_KERNEL_ADDRESS(virtualAddress)) {
                        addressSpace = VMAddressSpace::Kernel();
-               } else if (!teamSpecified || teamID == B_CURRENT_TEAM) {
+               } else if (team != NULL) {
+                       addressSpace = team->address_space;
+               } else {
                        Thread* thread = debug_get_debugged_thread();
                        if (thread == NULL || thread->team == NULL) {
                                kprintf("Failed to get team!\n");
@@ -3535,8 +3534,7 @@ dump_mapping_info(int argc, char** argv)
                        }
 
                        addressSpace = thread->team->address_space;
-               } else
-                       addressSpace = VMAddressSpace::DebugGet(teamID);
+               }
 
                if (addressSpace == NULL) {
                        kprintf("Failed to get address space!\n");
@@ -4078,16 +4076,17 @@ vm_init(kernel_args* args)
 
        add_debugger_command_etc("mapping", &dump_mapping_info,
                "Print address mapping information",
-               "[ \"-r\" | \"-p\" ] <address> [ <team ID> ]\n"
+               "[ \"-r\" | \"-p\" ] <address> [ <thread ID> ]\n"
                "Prints low-level page mapping information for a given address. 
If\n"
                "neither \"-r\" nor \"-p\" are specified, <address> is a 
virtual\n"
                "address that is looked up in the translation map of the 
current\n"
-               "team, respectively the team specified by ID <team ID>. If 
\"-r\" is\n"
-               "specified, <address> is a physical address that is searched in 
the\n"
-               "translation map of all teams, respectively the team specified 
by ID\n"
-               " <team ID>. If \"-p\" is specified, <address> is the address 
of a\n"
-               "vm_page structure. The behavior is equivalent to specifying 
\"-r\"\n"
-               "with the physical address of that page.\n",
+               "team, respectively the team specified by thread ID <thread 
ID>. If\n"
+               "\"-r\" is specified, <address> is a physical address that is\n"
+               "searched in the translation map of all teams, respectively the 
team\n"
+               "specified by thread ID <thread ID>. If \"-p\" is specified,\n"
+               "<address> is the address of a vm_page structure. The behavior 
is\n"
+               "equivalent to specifying \"-r\" with the physical address of 
that\n"
+               "page.\n",
                0);
 
        TRACE(("vm_init: exit\n"));


Other related posts: