Bir pKVM satıcı modülünü uygulayın

Bu sayfada korumalı çekirdek tabanlı sanal makine (pKVM) satıcı modülünün nasıl uygulanacağı açıklanmaktadır. Bu adımları tamamladığınızda aşağıdakine benzer bir dizin ağacına sahip olmalısınız:

Makefile
el1.c
hyp/
    Makefile
    el2.c
  1. EL2 hiper yönetici kodunu ( el2.c ) ekleyin. Bu kodun en azından pkvm_module_ops yapısına bir referansı kabul eden bir init işlevi bildirmesi gerekir:

    #include <asm/kvm_pkvm_module.h>
    
    int pkvm_driver_hyp_init(const struct pkvm_module_ops *ops)
    {
      /* Init the EL2 code */
    
      return 0;
    }
    

    pKVM satıcı modülü API'si, pKVM hipervizörüne yapılan geri aramaları kapsayan bir yapıdır. Bu yapı, GKI arayüzleriyle aynı ABI kurallarına uyar.

  2. Hipervizör kodunu oluşturmak için hyp/Makefile dosyasını oluşturun:

    hyp-obj-y := el2.o
    include $(srctree)/arch/arm64/kvm/hyp/nvhe/Makefile.module
    
  3. EL1 çekirdek kodunu ( el1.c ) ekleyin. Bu kodun başlangıç ​​bölümü, 1. adımdan itibaren EL2 hipervizör kodunu yüklemek için pkvm_load_el2 module bir çağrı içermelidir.

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <asm/kvm_pkvm_module.h>
    
    int __kvm_nvhe_pkvm_driver_hyp_init(const struct pkvm_module_ops *ops);
    
    static int __init pkvm_driver_init(void)
    {
        unsigned long token;
    
        return pkvm_load_el2_module(__kvm_nvhe_pkvm_driver_hyp_init, &token);
    }
    module_init(pkvm_driver_init);
    
  4. Son olarak EL1 ve EL2 kodunu birbirine bağlamak için kök makefile dosyasını oluşturun:

    ifneq ($(KERNELRELEASE),)
    clean-files := hyp/hyp.lds hyp/hyp-reloc.S
    
    obj-m := pkvm_module.o
    pkvm_module-y := el1.o hyp/kvm_nvhe.o
    
    $(PWD)/hyp/kvm_nvhe.o: FORCE
             $(Q)$(MAKE) $(build)=$(obj)/hyp $(obj)/hyp/kvm_nvhe.o
    else
    all:
            make -C $(KDIR) M=$(PWD) modules
    clean:
            make -C $(KDIR) M=$(PWD) clean
    endif
    

Bir pKVM modülü yükleyin

GKI satıcı modüllerinde olduğu gibi, pKVM satıcı modülleri de modprobe kullanılarak yüklenebilir. Ancak güvenlik nedeniyle yüklemenin ayrıcalıktan yararlanmadan önce gerçekleşmesi gerekir. Bir pKVM modülünü yüklemek için modüllerinizin kök dosya sistemine ( initramfs ) dahil edildiğinden emin olmalısınız ve aşağıdakileri çekirdek komut satırınıza eklemelisiniz:

kvm-arm.protected_modules= mod1 , mod2 , mod3 , ...

initramfs saklanan pKVM satıcı modülleri, initramfs imzasını ve korumasını devralır.

pKVM satıcı modüllerinden birinin yüklenememesi halinde sistemin güvensiz olduğu kabul edilir ve korumalı bir sanal makinenin başlatılması mümkün olmayacaktır.

EL2'den (çekirdek modülü) bir EL2 (hiper yönetici) işlevini çağırın

Hipervizör çağrısı (HVC), çekirdeğin hipervizörü çağırmasına olanak tanıyan bir talimattır. pKVM satıcı modüllerinin kullanıma sunulmasıyla birlikte, EL1'den (çekirdek modülü) EL2'de (hipervizör modülünde) çalışacak bir işlevi çağırmak için bir HVC kullanılabilir:

  1. EL2 kodunda ( el2.c ), EL2 işleyicisini bildirin:

    void pkvm_driver_hyp_hvc(struct kvm_cpu_context *ctx)
    {
      /* Handle the call */
    
      cpu_reg(ctx, 1) = 0;
    }
    
  2. EL1 kodunuzda ( el1.c ), EL2 işleyicisini pKVM satıcı modülünüze kaydedin:

    int __kvm_nvhe_pkvm_driver_hyp_init(const struct pkvm_module_ops *ops);
    void __kvm_nvhe_pkvm_driver_hyp_hvc(struct kvm_cpu_context *ctx);
    
    static int hvc_number;
    
    static int __init pkvm_driver_init(void)
    {
      long token;
      int ret;
    
      ret = pkvm_load_el2_module(__kvm_nvhe_pkvm_driver_hyp_init,token);
      if (ret)
        return ret;
    
      ret = pkvm_register_el2_mod_call(__kvm_nvhe_pkvm_driver_hyp_hvc, token)
      if (ret < 0)
        return ret;
    
      hvc_number = ret;
    
      return 0;
    }
    module_init(pkvm_driver_init);
    
  3. EL1 kodunuzda ( el1.c ), HVC'yi arayın:

    pkvm_el2_mod_call(hvc_number);