• libvirt e nested paging

    Data:2010.09.01 | Categoriaservidores, virtualização | Tags: ,

    Embora o qemu-kvm já tenha suporte à páginas aninhadas (nested pages), a última versão do libvirt-0.8.3 ainda não suporta.

    Apenas para esclarecer, Nested Paging é um recurso disponível apenas para processadores AMD da linha Phenom ou superior. Maiores detalhes, consulte este documento.

    Pesquisei por referências de como habilitar a opção ‘-enable-nesting’ do qemu-kvm no libvirt, mas não encontrei. Depois de pelo menos 2 dezenas de cliques, eis que encontro na lista de e-mails dos desenvolvedores do libvirt referências já antigas (novembro de 2009), de como usar o nesting. Pois bem, meu trabalho se resumiu em ler certinho as mensagens e montar um patch. Mesmo que a versão que estou usando (0.8.3) seja muito mais nova que esse post, testei as alterações, e que maravilha, funcionou!!!

    Depois de compilado e instalado, só precisei acrescentar na definição do domínio dentro da tag <features> uma tag <nesting/>. Depois disso é só iniciar a VM e ver que na linha de comando da sua máquina virtual tem o -enable-nesting.

    Agradeço demais a equipe de desenvolvimento de qemu-kvm e libvirt!

    Abaixo segue o meu patch para libvirt-0.8.3:

    diff -Naur ../libvirt-0.8.3//docs/schemas/domain.rng ./docs/schemas/domain.rng
    --- ../libvirt-0.8.3//docs/schemas/domain.rng   2010-07-29 06:48:30.000000000 -0300
    +++ ./docs/schemas/domain.rng   2010-09-01 16:51:57.710851479 -0300
    @@ -1595,6 +1595,11 @@
                   <empty/>
                 </element>
               </optional>
    +          <optional>
    +           <element name="nesting">
    +             <empty/>
    +           </element>
    +         </optional>
             </interleave>
           </element>
         </optional>
    diff -Naur ../libvirt-0.8.3//src/conf/domain_conf.c ./src/conf/domain_conf.c
    --- ../libvirt-0.8.3//src/conf/domain_conf.c    2010-08-02 16:16:42.000000000 -0300
    +++ ./src/conf/domain_conf.c    2010-09-01 16:51:57.710851479 -0300
    @@ -75,7 +75,8 @@
     VIR_ENUM_IMPL(virDomainFeature, VIR_DOMAIN_FEATURE_LAST,
                   "acpi",
                   "apic",
    -              "pae")
    +              "pae",
    +             "nesting")
    
     VIR_ENUM_IMPL(virDomainLifecycle, VIR_DOMAIN_LIFECYCLE_LAST,
                   "destroy",
    diff -Naur ../libvirt-0.8.3//src/conf/domain_conf.h ./src/conf/domain_conf.h
    --- ../libvirt-0.8.3//src/conf/domain_conf.h    2010-07-29 06:48:30.000000000 -0300
    +++ ./src/conf/domain_conf.h    2010-09-01 16:51:57.710851479 -0300
    @@ -649,6 +649,7 @@
         VIR_DOMAIN_FEATURE_ACPI,
         VIR_DOMAIN_FEATURE_APIC,
         VIR_DOMAIN_FEATURE_PAE,
    +    VIR_DOMAIN_FEATURE_NESTING,
    
         VIR_DOMAIN_FEATURE_LAST
     };
    diff -Naur ../libvirt-0.8.3//src/qemu/qemu_conf.c ./src/qemu/qemu_conf.c
    --- ../libvirt-0.8.3//src/qemu/qemu_conf.c      2010-08-04 09:21:27.000000000 -0300
    +++ ./src/qemu/qemu_conf.c      2010-09-01 16:57:47.485469640 -0300
    @@ -1190,6 +1190,8 @@
             flags |= QEMUD_CMD_FLAG_MEM_PATH;
         if (strstr(help, "-chardev"))
             flags |= QEMUD_CMD_FLAG_CHARDEV;
    +    if (strstr(help, "-enable-nesting"))
    +        flags |= QEMUD_CMD_FLAG_NESTING;
         if (strstr(help, "-balloon"))
             flags |= QEMUD_CMD_FLAG_BALLOON;
         if (strstr(help, "-device"))
    @@ -3907,6 +3909,9 @@
                 goto error;
             }
         }
    +    if ((qemuCmdFlags & QEMUD_CMD_FLAG_NESTING) &&
    +        (def->features & (1 << VIR_DOMAIN_FEATURE_NESTING)))
    +        ADD_ARG_LIT("-enable-nesting");
    
         /*
          * NB, -nographic *MUST* come before any serial, or monitor
    @@ -6265,6 +6270,8 @@
                 fullscreen = 1;
             } else if (STREQ(arg, "-localtime")) {
                 def->clock.offset = VIR_DOMAIN_CLOCK_OFFSET_LOCALTIME;
    +        } else if (STREQ(arg, "-enable-nesting")) {
    +            def->features |= (1 << VIR_DOMAIN_FEATURE_NESTING);
             } else if (STREQ(arg, "-kernel")) {
                 WANT_VALUE();
                 if (!(def->os.kernel = strdup(val)))
    diff -Naur ../libvirt-0.8.3//src/qemu/qemu_conf.h ./src/qemu/qemu_conf.h
    --- ../libvirt-0.8.3//src/qemu/qemu_conf.h      2010-07-28 11:18:15.000000000 -0300
    +++ ./src/qemu/qemu_conf.h      2010-09-01 16:58:29.900876561 -0300
    @@ -92,6 +92,7 @@
         QEMUD_CMD_FLAG_PCI_CONFIGFD  = (1LL << 36), /* pci-assign.configfd */
         QEMUD_CMD_FLAG_NODEFCONFIG   = (1LL << 37), /* -nodefconfig */
         QEMUD_CMD_FLAG_BOOT_MENU     = (1LL << 38), /* -boot menu=on support */
    +    QEMUD_CMD_FLAG_NESTING       = (1LL << 39), /* Is the -enable-nesting flag available */
     };
    
     /* Main driver state */