云网牛站
所在位置:首页 > Linux教程 > Virtualbox在Linux 5.10内核或以上不能使用的解决办法

Virtualbox在Linux 5.10内核或以上不能使用的解决办法

2020-12-20 10:24:29作者:rekees2020稿源:深度站

在Deepin 20系统中升级到了Linux 5.10内核,但是Virtualbox不能正常使用,当前VirtualBox 6.1.16及以下版本应该还没有支持Linux 5.10内核或以上版本(参考:虚拟机VirtualBox 6.1.16发布下载:支持Linux 5.9内核),由于有一些软件必需要在虚拟机中运行,所以就不等Virtualbox的补丁了,直接动手解决问题。

 

解决办法

请前往以下链接:

https://www.virtualbox.org/attachment/ticket/20055/linux-5.10-r0drv-memobj-fix-r0.patch

这是一个补丁,我们需要做的就是修改src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c,这个补丁修复了编译内核模块及在Linux 5.10上运行的问题,代码中的红色表示删除掉,绿色为添加的,修改后运行sudo /sbin/vboxconfig就可以了。

1]、以下是修改memobj-r0drv-linux.c的方法:

该文件的位置在usr/share/virtualbox/src/vboxhost/vboxdrv/r0drv/linux/memobj-r0drv-linux.c,建议先备份好文件,然后运行sudo dedit /usr/share/virtualbox/src/vboxhost/vboxdrv/r0drv/linux/memobj-r0drv-linux.c,打开该文件后进行修改并保存修改过的文件即可。

注:经过修改后通常都不报错了,能正常的运行。

2]、memobj-r0drv-linux.c文件图示:

Virtualbox在Linux 5.10内核或以上不能使用的解决办法

3]、文件代码如下,供参考:

 * Whether we use alloc_vm_area (3.2+) for executable memory. 

 * This is a must for 5.8+, but we enable it all the way back to 3.2.x for 

 * better W^R compliance (fExecutable flag). */ 

#if RTLNX_VER_RANGE(3,2,0, 5,10,0) || defined(DOXYGEN_RUNNING) 

# define IPRT_USE_ALLOC_VM_AREA_FOR_EXEC 

#endif 

#if RTLNX_VER_MIN(5,10,0) || defined(DOXYGEN_RUNNING) 

# define IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC 

#endif 

/* 

 * 2.6.29+ kernels don't work with remap_pfn_range() anymore because 

#ifdef IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC 

/** 

 * User data passed to the apply_to_page_range() callback. 

 */ 

typedef struct LNXAPPLYPGRANGE 

   /** Pointer to the memory object. */ 

   PRTR0MEMOBJLNX pMemLnx; 

   /** The page protection flags to apply. */ 

   pgprot_t       fPg; 

} LNXAPPLYPGRANGE; 

/** Pointer to the user data. */ 

typedef LNXAPPLYPGRANGE *PLNXAPPLYPGRANGE; 

/** Pointer to the const user data. */ 

typedef const LNXAPPLYPGRANGE *PCLNXAPPLYPGRANGE; 

/** 

 * Callback called in apply_to_page_range(). 

 * 

 * @returns Linux status code. 

 * @param   pPte                Pointer to the page table entry for the given address. 

 * @param   uAddr               The address to apply the new protection to. 

 * @param   pvUser              The opaque user data. 

 */ 

static DECLCALLBACK(int) rtR0MemObjLinuxApplyPageRange(pte_t *pPte, unsigned long uAddr, void *pvUser) 

   PCLNXAPPLYPGRANGE pArgs = (PCLNXAPPLYPGRANGE)pvUser; 

   PRTR0MEMOBJLNX pMemLnx = pArgs->pMemLnx; 

   uint32_t idxPg = (uAddr - (unsigned long)pMemLnx->Core.pv) >> PAGE_SHIFT; 

   set_pte(pPte, mk_pte(pMemLnx->apPages[idxPg], pArgs->fPg)); 

   return 0; 

#endif 

/** 

 * Maps the allocation into ring-0. 

 * 

 * This will update the RTR0MEMOBJLNX::Core.pv and RTR0MEMOBJ::fMappedToRing0 members. 

       else 

# endif 

      { 

#  if defined(IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC) 

        if (fExecutable) 

         pgprot_val(fPg) |= _PAGE_NX; /* Uses RTR0MemObjProtect to clear NX when memory ready, W^X fashion. */ 

#  endif 

# ifdef VM_MAP 

       pMemLnx->Core.pv = vmap(&pMemLnx->apPages[0], pMemLnx->cPages, VM_MAP, fPg); 

# else 

     preempt_enable(); 

     return VINF_SUCCESS; 

# elif defined(IPRT_USE_APPLY_TO_PAGE_RANGE_FOR_EXEC) 

    PRTR0MEMOBJLNX pMemLnx = (PRTR0MEMOBJLNX)pMem; 

   if (   pMemLnx->fExecutable 

       && pMemLnx->fMappedToRing0) 

  { 

      LNXAPPLYPGRANGE Args; 

     Args.pMemLnx = pMemLnx; 

     Args.fPg = rtR0MemObjLinuxConvertProt(fProt, true /*fKernel*/); 

     int rcLnx = apply_to_page_range(current->active_mm, (unsigned long)pMemLnx->Core.pv + offSub, cbSub, 

                          rtR0MemObjLinuxApplyPageRange, (void *)&Args); 

      if (rcLnx) 

        return VERR_NOT_SUPPORTED; 

     return VINF_SUCCESS; 

   } 

# endif

    NOREF(pMem);

 

注意

如果你使用的VirtualBox版本是6.1.16或以下,请按上面的要求修改文件,如果使用的是更高版本,那么VirtualBox必然已修复了对Linux 5.10兼容的问题,请不需要修改了。

 

相关主题

在Linux中从命令行查找Virtualbox Version的方法

精选文章
热门文章