diff --git a/qemu-options.hx b/qemu-options.hx
index 166eae6..9216b02 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -6,17 +6,80 @@ HXCOMM construct option structures, enums and help message for specified
 HXCOMM architectures.
 HXCOMM HXCOMM can be used for comments, discarded from both texi and C
 
-DEFHEADING(Standard options:)
+#if defined(QEMU_HELP_SELECT_HELP) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_HELP
+DEFHEADING(Help/version options:)
 STEXI
 @table @option
 ETEXI
 
 DEF("help", 0, QEMU_OPTION_h,
-    "-h or -help     display this help and exit\n", QEMU_ARCH_ALL)
-STEXI
-@item -h
+    "-h|-help[=section[,...]]\n"
+    "                list help options.\n"
+    "                You can provide the list of sections to display.\n"
+    "                available sections are:\n"
+    "                all,help,standard,block,usb,display,machine,network,\n"
+    "                character,url,bt,tpm,kernel,expert,object\n" , QEMU_ARCH_ALL)
+STEXI
+@item -help [section][,...]
 @findex -h
-Display help and exit
+list help options.
+
+You can provide the list of sections to display:
+@table @option
+@item all
+display all sections
+@item help
+display help options
+@item standard
+display standard options
+@item block
+display block options
+@item usb
+display usb options
+@item display
+display display options
+@item machine
+display machine options
+@item network
+display network options
+@item character
+display character options
+@item url
+display url options
+@item bt
+display bt options
+@item tpm
+display tpm options
+@item kernel
+display kernel options
+@item expert
+display expert options
+@item object
+display object options
+@end table
+
+'-help' without option displays help options.
+
+@example
+Example:
+    $ x86_64-softmmu/qemu-system-x86_64 -help=kernel,usb
+    QEMU emulator version 2.4.50, Copyright (c) 2003-2008 Fabrice Bellard
+    usage: qemu-system-x86_64 [options] [disk_image]
+
+    'disk_image' is a raw hard disk image for IDE hard disk 0
+
+    Linux/Multiboot boot specific:
+    -kernel bzImage use 'bzImage' as kernel image
+    -append cmdline use 'cmdline' as kernel command line
+    -initrd file    use 'file' as initial ram disk
+    -dtb    file    use 'file' as device tree image
+
+    USB options:
+    -usb            enable the USB driver (will be the default soon)
+    -usbdevice name add the host or guest USB device 'name'
+@end example
+
 ETEXI
 
 DEF("version", 0, QEMU_OPTION_version,
@@ -27,6 +90,19 @@ STEXI
 Display version information and exit
 ETEXI
 
+STEXI
+@end table
+ETEXI
+DEFHEADING()
+#endif
+
+#if defined(QEMU_HELP_SELECT_STANDARD) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_STANDARD
+DEFHEADING(Standard options:)
+STEXI
+@table @option
+ETEXI
+
 DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
     "-machine [type=]name[,prop[=value][,...]]\n"
     "                selects emulated machine ('-machine help' for list)\n"
@@ -413,7 +489,10 @@ STEXI
 @end table
 ETEXI
 DEFHEADING()
+#endif
 
+#if defined(QEMU_HELP_SELECT_BLOCK) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_BLOCK
 DEFHEADING(Block device options:)
 STEXI
 @table @option
@@ -801,7 +880,10 @@ STEXI
 @end table
 ETEXI
 DEFHEADING()
+#endif
 
+#if defined(QEMU_HELP_SELECT_USB) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_USB
 DEFHEADING(USB options:)
 STEXI
 @table @option
@@ -865,7 +947,10 @@ STEXI
 @end table
 ETEXI
 DEFHEADING()
+#endif
 
+#if defined(QEMU_HELP_SELECT_DISPLAY) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_DISPLAY
 DEFHEADING(Display options:)
 STEXI
 @table @option
@@ -1332,7 +1417,10 @@ STEXI
 @end table
 ETEXI
 ARCHHEADING(, QEMU_ARCH_I386)
+#endif
 
+#if defined(QEMU_HELP_SELECT_MACHINE) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_MACHINE
 ARCHHEADING(i386 target only:, QEMU_ARCH_I386)
 STEXI
 @table @option
@@ -1444,7 +1532,10 @@ STEXI
 @end table
 ETEXI
 DEFHEADING()
+#endif
 
+#if defined(QEMU_HELP_SELECT_NETWORK) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_NETWORK
 DEFHEADING(Network options:)
 STEXI
 @table @option
@@ -1998,7 +2089,10 @@ STEXI
 @end table
 ETEXI
 DEFHEADING()
+#endif
 
+#if defined(QEMU_HELP_SELECT_CHARACTER) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_CHARACTER
 DEFHEADING(Character device options:)
 STEXI
 
@@ -2276,7 +2370,10 @@ STEXI
 @end table
 ETEXI
 DEFHEADING()
+#endif
 
+#if defined(QEMU_HELP_SELECT_URL) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_URL
 DEFHEADING(Device URL Syntax:)
 STEXI
 
@@ -2485,7 +2582,10 @@ ETEXI
 STEXI
 @end table
 ETEXI
+#endif
 
+#if defined(QEMU_HELP_SELECT_BT) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_BT
 DEFHEADING(Bluetooth(R) options:)
 STEXI
 @table @option
@@ -2560,7 +2660,10 @@ STEXI
 @end table
 ETEXI
 DEFHEADING()
+#endif
 
+#if defined(QEMU_HELP_SELECT_TPM) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_TPM
 #ifdef CONFIG_TPM
 DEFHEADING(TPM device options:)
 
@@ -2635,7 +2738,10 @@ ETEXI
 DEFHEADING()
 
 #endif
+#endif
 
+#if defined(QEMU_HELP_SELECT_KERNEL) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_KERNEL
 DEFHEADING(Linux/Multiboot boot specific:)
 STEXI
 
@@ -2691,7 +2797,10 @@ STEXI
 @end table
 ETEXI
 DEFHEADING()
+#endif
 
+#if defined(QEMU_HELP_SELECT_EXPERT) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_EXPERT
 DEFHEADING(Debug/Expert options:)
 STEXI
 @table @option
@@ -3521,7 +3630,10 @@ STEXI
 Dump json-encoded vmstate information for current machine type to file
 in @var{file}
 ETEXI
+#endif
 
+#if defined(QEMU_HELP_SELECT_OBJECT) || !defined(QEMU_HELP_SELECT)
+#undef QEMU_HELP_SELECT_OBJECT
 DEFHEADING(Generic object creation)
 
 DEF("object", HAS_ARG, QEMU_OPTION_object,
@@ -3574,7 +3686,7 @@ to the RNG daemon.
 @end table
 
 ETEXI
-
+#endif
 
 HXCOMM This is the last statement. Insert new options before this line!
 STEXI
diff --git a/vl.c b/vl.c
index 586ce55..5d05dee 100644
--- a/vl.c
+++ b/vl.c
@@ -1916,15 +1916,167 @@ static void version(void)
     printf("QEMU emulator version " QEMU_VERSION QEMU_PKGVERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n");
 }
 
-static void help(int exitcode)
+#define QEMU_HELP_SELECT
+static void help_help(void)
 {
+#define QEMU_HELP_SELECT_HELP
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+static void help_standard(void)
+{
+#define QEMU_HELP_SELECT_STANDARD
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+static void help_block(void)
+{
+#define QEMU_HELP_SELECT_BLOCK
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+static void help_usb(void)
+{
+#define QEMU_HELP_SELECT_USB
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+static void help_display(void)
+{
+#define QEMU_HELP_SELECT_DISPLAY
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+static void help_machine(void)
+{
+#define QEMU_HELP_SELECT_MACHINE
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+static void help_network(void)
+{
+#define QEMU_HELP_SELECT_NETWORK
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+static void help_character(void)
+{
+#define QEMU_HELP_SELECT_CHARACTER
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+static void help_url(void)
+{
+#define QEMU_HELP_SELECT_URL
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+static void help_bt(void)
+{
+#define QEMU_HELP_SELECT_BT
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+#ifdef CONFIG_TPM
+static void help_tpm(void)
+{
+#define QEMU_HELP_SELECT_TPM
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+#endif
+static void help_kernel(void)
+{
+#define QEMU_HELP_SELECT_KERNEL
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+static void help_expert(void)
+{
+#define QEMU_HELP_SELECT_EXPERT
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+static void help_object(void)
+{
+#define QEMU_HELP_SELECT_OBJECT
+#define QEMU_OPTIONS_GENERATE_HELP
+#include "qemu-options-wrapper.h"
+}
+#undef QEMU_HELP_SELECT
+
+#define SUBHELP(n) { .name = #n, .handler = help_##n }
+typedef struct {
+    const char *name;
+    void (*handler)(void);
+} QEMUHelpOptions;
+
+static void help_all(void);
+static QEMUHelpOptions help_handler[] = {
+    SUBHELP(all), /* must be the first */
+    SUBHELP(standard),
+    SUBHELP(block),
+    SUBHELP(usb),
+    SUBHELP(display),
+    SUBHELP(machine),
+    SUBHELP(network),
+    SUBHELP(character),
+    SUBHELP(url),
+    SUBHELP(bt),
+#ifdef CONFIG_TPM
+    SUBHELP(tpm),
+#endif
+    SUBHELP(kernel),
+    SUBHELP(expert),
+    SUBHELP(object),
+    SUBHELP(help),
+    { NULL, NULL }
+};
+
+static void help_all(void)
+{
+    int i;
+
+    for (i = 1; help_handler[i].handler; i++) {
+        help_handler[i].handler();
+    }
+}
+
+static void help(const char *optarg, int exitcode)
+{
+    const char *p, *e;
+    size_t l;
+    int i;
+
     version();
     printf("usage: %s [options] [disk_image]\n\n"
            "'disk_image' is a raw hard disk image for IDE hard disk 0\n\n",
             error_get_progname());
 
-#define QEMU_OPTIONS_GENERATE_HELP
-#include "qemu-options-wrapper.h"
+    if (optarg == NULL) {
+        help_help();
+        exit(exitcode);
+    }
+
+    p = optarg;
+    while (*p) {
+        e = strchr(p, ',');
+        l = !e ? strlen(p) : (size_t) (e - p);
+        for (i = 0; help_handler[i].handler; i++) {
+            if (l != strlen(help_handler[i].name)) {
+                continue;
+            }
+            if (strncmp(help_handler[i].name, p, l) == 0) {
+                break;
+            }
+        }
+        if (help_handler[i].handler) {
+            help_handler[i].handler();
+        } else {
+            printf("Unknown help option \"%.*s\"\n", (int)l, p);
+        }
+        p += l + (e != NULL);
+    }
 
     printf("\nDuring emulation, the following keys are useful:\n"
            "ctrl-alt-f      toggle full screen\n"
@@ -3330,7 +3482,7 @@ int main(int argc, char **argv, char **envp)
                 select_soundhw (optarg);
                 break;
             case QEMU_OPTION_h:
-                help(0);
+                help(optarg, 0);
                 break;
             case QEMU_OPTION_version:
                 version();
