компиляция модулей ядра и технология Intel GVTg

Автор newcomer, 17 сентября 2019, 15:46:08

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

newcomer

Добрый день,

Требуется пробросить видеокарту Intel в виртуальную машину. Для это обратился к технологии Intel GVTg.
Ноутбук Dell inspiron 7460. Конфигурация следующая


_,met$$$$$gg.           gamer@debian
      ,g$$$$$$$$$$$$$$$P.        OS: Debian 10 buster
    ,g$$P""       """Y$$.".      Kernel: x86_64 Linux 4.19.0-6-amd64
   ,$$P'              `$$$.      Uptime: 27m
  ',$$P       ,ggs.     `$$b:    Packages: 1012
  `d$$'     ,$P"'   .    $$$     Shell: bash 5.0.3
   $$P      d$'     ,    $$P     Resolution: 1920x1080
   $$:      $$.   -    ,d$$'     DE: XFCE
   $$\;      Y$b._   _,d$P'      WM: Xfwm4
   Y$$.    `.`"Y$$$$P"'          WM Theme: mac
   `$$b      "-.__               GTK Theme: Mojave-light-solid-alt [GTK2]
    `Y$$                         Icon Theme: Os-Catalina-icons
     `Y$$.                       Font: Sans 10
       `$$b.                     CPU: Intel Core i7-7500U @ 4x 3.5GHz [25.0°C]
         `Y$$b.                  GPU: Mesa DRI Intel(R) HD Graphics 620 (Kaby Lake GT2)
            `"Y$b._              RAM: 929MiB / 16005MiB
                `""""           



В немного численных мануалах написано,что надо собрать недостающие модули для ядра 4.19 - vfio-mdev, kvmgt.
Скачал исходники ядра. Значения конфига установил следующие


CONFIG_DRM_I915_USERPTR=y
CONFIG_DRM_I915_GVT=y
CONFIG_DRM_I915_GVT_KVMGT=m

CONFIG_VFIO_NOIOMMU is not set

CONFIG_VFIO_MDEV=m
CONFIG_VFIO_MDEV_DEVICE=m

CONFIG_VHOST_NET=m


Модуль vfio-mdev собрался и запустился без проблем,а вот kvmgt возникли проблемы, во время компиляции.


  CC [M]  drivers/gpu/drm/i915/gvt/dmabuf.o
  CC [M]  drivers/gpu/drm/i915/gvt/page_track.o
  CC [M]  drivers/gpu/drm/i915/intel_lpe_audio.o
  LD [M]  drivers/gpu/drm/i915/i915.o
  Building modules, stage 2.
  MODPOST 2 modules
WARNING: "mdev_set_drvdata" [drivers/gpu/drm/i915/gvt/kvmgt.ko] undefined!
WARNING: "mdev_unregister_device" [drivers/gpu/drm/i915/gvt/kvmgt.ko] undefined!
WARNING: "mdev_dev" [drivers/gpu/drm/i915/gvt/kvmgt.ko] undefined!
WARNING: "mdev_register_device" [drivers/gpu/drm/i915/gvt/kvmgt.ko] undefined!
WARNING: "mdev_get_drvdata" [drivers/gpu/drm/i915/gvt/kvmgt.ko] undefined!
WARNING: "mdev_parent_dev" [drivers/gpu/drm/i915/gvt/kvmgt.ko] undefined!
WARNING: "mdev_from_dev" [drivers/gpu/drm/i915/gvt/kvmgt.ko] undefined!
  CC      drivers/gpu/drm/i915/gvt/kvmgt.mod.o
  LD [M]  drivers/gpu/drm/i915/gvt/kvmgt.ko
  CC      drivers/gpu/drm/i915/i915.mod.o
  LD [M]  drivers/gpu/drm/i915/i915.ko
make: Leaving directory '/home/gamer/Downloads/linux-source-4.19


Ошибки возникли только в конце, но как видно из лога модуль собрался.
Используя команду sudo modprobe -f kvmgt модуль можно запустить, но работоспособность отстутсвует. И как результат директоря mdev_supported_types не доступна.
Вот последнии строки dmesg

[   83.998721] kvmgt: no symbol version for mdev_from_dev
[   83.998727] kvmgt: Unknown symbol mdev_from_dev (err -22)
[   83.999096] kvmgt: no symbol version for mdev_parent_dev
[   83.999099] kvmgt: Unknown symbol mdev_parent_dev (err -22)
[   83.999664] kvmgt: no symbol version for mdev_get_drvdata
[   83.999666] kvmgt: Unknown symbol mdev_get_drvdata (err -22)
[   83.999727] kvmgt: no symbol version for mdev_register_device
[   83.999730] kvmgt: Unknown symbol mdev_register_device (err -22)
[   83.999792] kvmgt: no symbol version for mdev_dev
[   83.999794] kvmgt: Unknown symbol mdev_dev (err -22)
[   83.999849] kvmgt: no symbol version for mdev_unregister_device
[   83.999851] kvmgt: Unknown symbol mdev_unregister_device (err -22)
[   84.000023] kvmgt: no symbol version for mdev_set_drvdata
[   84.000025] kvmgt: Unknown symbol mdev_set_drvdata (err -22)
[   91.861591] kvmgt: module_layout: kernel tainted.
[   91.861593] Disabling lock debugging due to kernel taint


В чём может заключаться проблема?
Гугл молчит.

newcomer

Ещё раз посмотрет на ошибки и пришла в голову мысль, может быть не врено  скомпилировал модуль vfio_mdev. В директории с иходниками есть файл mdev_core.c Вот в нём и встречаются все это значения,которые undefined.


/*
* Mediated device Core Driver
*
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
*     Author: Neo Jia <cjia@nvidia.com>
*             Kirti Wankhede <kwankhede@nvidia.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#include <linux/module.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/uuid.h>
#include <linux/sysfs.h>
#include <linux/mdev.h>

#include "mdev_private.h"

#define DRIVER_VERSION "0.1"
#define DRIVER_AUTHOR "NVIDIA Corporation"
#define DRIVER_DESC "Mediated device Core Driver"

static LIST_HEAD(parent_list);
static DEFINE_MUTEX(parent_list_lock);
static struct class_compat *mdev_bus_compat_class;

static LIST_HEAD(mdev_list);
static DEFINE_MUTEX(mdev_list_lock);

struct device *mdev_parent_dev(struct mdev_device *mdev)
{
return mdev->parent->dev;
}
EXPORT_SYMBOL(mdev_parent_dev);

void *mdev_get_drvdata(struct mdev_device *mdev)
{
return mdev->driver_data;
}
EXPORT_SYMBOL(mdev_get_drvdata);

void mdev_set_drvdata(struct mdev_device *mdev, void *data)
{
mdev->driver_data = data;
}
EXPORT_SYMBOL(mdev_set_drvdata);

struct device *mdev_dev(struct mdev_device *mdev)
{
return &mdev->dev;
}
EXPORT_SYMBOL(mdev_dev);

struct mdev_device *mdev_from_dev(struct device *dev)
{
return dev_is_mdev(dev) ? to_mdev_device(dev) : NULL;
}
EXPORT_SYMBOL(mdev_from_dev);

uuid_le mdev_uuid(struct mdev_device *mdev)
{
return mdev->uuid;
}
EXPORT_SYMBOL(mdev_uuid);

/* Should be called holding parent_list_lock */
static struct mdev_parent *__find_parent_device(struct device *dev)
{
struct mdev_parent *parent;

list_for_each_entry(parent, &parent_list, next) {
if (parent->dev == dev)
return parent;
}
return NULL;
}

static void mdev_release_parent(struct kref *kref)
{
struct mdev_parent *parent = container_of(kref, struct mdev_parent,
  ref);
struct device *dev = parent->dev;

kfree(parent);
put_device(dev);
}

static
inline struct mdev_parent *mdev_get_parent(struct mdev_parent *parent)
{
if (parent)
kref_get(&parent->ref);

return parent;
}

static inline void mdev_put_parent(struct mdev_parent *parent)
{
if (parent)
kref_put(&parent->ref, mdev_release_parent);
}

static int mdev_device_create_ops(struct kobject *kobj,
  struct mdev_device *mdev)
{
struct mdev_parent *parent = mdev->parent;
int ret;

ret = parent->ops->create(kobj, mdev);
if (ret)
return ret;

ret = sysfs_create_groups(&mdev->dev.kobj,
  parent->ops->mdev_attr_groups);
if (ret)
parent->ops->remove(mdev);

return ret;
}

/*
* mdev_device_remove_ops gets called from sysfs's 'remove' and when parent
* device is being unregistered from mdev device framework.
* - 'force_remove' is set to 'false' when called from sysfs's 'remove' which
*   indicates that if the mdev device is active, used by VMM or userspace
*   application, vendor driver could return error then don't remove the device.
* - 'force_remove' is set to 'true' when called from mdev_unregister_device()
*   which indicate that parent device is being removed from mdev device
*   framework so remove mdev device forcefully.
*/
static int mdev_device_remove_ops(struct mdev_device *mdev, bool force_remove)
{
struct mdev_parent *parent = mdev->parent;
int ret;

/*
* Vendor driver can return error if VMM or userspace application is
* using this mdev device.
*/
ret = parent->ops->remove(mdev);
if (ret && !force_remove)
return -EBUSY;

sysfs_remove_groups(&mdev->dev.kobj, parent->ops->mdev_attr_groups);
return 0;
}

static int mdev_device_remove_cb(struct device *dev, void *data)
{
if (!dev_is_mdev(dev))
return 0;

return mdev_device_remove(dev, data ? *(bool *)data : true);
}

/*
* mdev_register_device : Register a device
* @dev: device structure representing parent device.
* @ops: Parent device operation structure to be registered.
*
* Add device to list of registered parent devices.
* Returns a negative value on error, otherwise 0.
*/
int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
{
int ret;
struct mdev_parent *parent;

/* check for mandatory ops */
if (!ops || !ops->create || !ops->remove || !ops->supported_type_groups)
return -EINVAL;

dev = get_device(dev);
if (!dev)
return -EINVAL;

mutex_lock(&parent_list_lock);

/* Check for duplicate */
parent = __find_parent_device(dev);
if (parent) {
ret = -EEXIST;
goto add_dev_err;
}

parent = kzalloc(sizeof(*parent), GFP_KERNEL);
if (!parent) {
ret = -ENOMEM;
goto add_dev_err;
}

kref_init(&parent->ref);

parent->dev = dev;
parent->ops = ops;

if (!mdev_bus_compat_class) {
mdev_bus_compat_class = class_compat_register("mdev_bus");
if (!mdev_bus_compat_class) {
ret = -ENOMEM;
goto add_dev_err;
}
}

ret = parent_create_sysfs_files(parent);
if (ret)
goto add_dev_err;

ret = class_compat_create_link(mdev_bus_compat_class, dev, NULL);
if (ret)
dev_warn(dev, "Failed to create compatibility class link\n");

list_add(&parent->next, &parent_list);
mutex_unlock(&parent_list_lock);

dev_info(dev, "MDEV: Registered\n");
return 0;

add_dev_err:
mutex_unlock(&parent_list_lock);
if (parent)
mdev_put_parent(parent);
else
put_device(dev);
return ret;
}
EXPORT_SYMBOL(mdev_register_device);

/*
* mdev_unregister_device : Unregister a parent device
* @dev: device structure representing parent device.
*
* Remove device from list of registered parent devices. Give a chance to free
* existing mediated devices for given device.
*/

void mdev_unregister_device(struct device *dev)
{
struct mdev_parent *parent;
bool force_remove = true;

mutex_lock(&parent_list_lock);
parent = __find_parent_device(dev);

if (!parent) {
mutex_unlock(&parent_list_lock);
return;
}
dev_info(dev, "MDEV: Unregistering\n");

list_del(&parent->next);
class_compat_remove_link(mdev_bus_compat_class, dev, NULL);

device_for_each_child(dev, (void *)&force_remove,
      mdev_device_remove_cb);

parent_remove_sysfs_files(parent);

mutex_unlock(&parent_list_lock);
mdev_put_parent(parent);
}
EXPORT_SYMBOL(mdev_unregister_device);

static void mdev_device_release(struct device *dev)
{
struct mdev_device *mdev = to_mdev_device(dev);

mutex_lock(&mdev_list_lock);
list_del(&mdev->next);
mutex_unlock(&mdev_list_lock);

dev_dbg(&mdev->dev, "MDEV: destroying\n");
kfree(mdev);
}

int mdev_device_create(struct kobject *kobj, struct device *dev, uuid_le uuid)
{
int ret;
struct mdev_device *mdev, *tmp;
struct mdev_parent *parent;
struct mdev_type *type = to_mdev_type(kobj);

parent = mdev_get_parent(type->parent);
if (!parent)
return -EINVAL;

mutex_lock(&mdev_list_lock);

/* Check for duplicate */
list_for_each_entry(tmp, &mdev_list, next) {
if (!uuid_le_cmp(tmp->uuid, uuid)) {
mutex_unlock(&mdev_list_lock);
ret = -EEXIST;
goto mdev_fail;
}
}

mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
if (!mdev) {
mutex_unlock(&mdev_list_lock);
ret = -ENOMEM;
goto mdev_fail;
}

memcpy(&mdev->uuid, &uuid, sizeof(uuid_le));
list_add(&mdev->next, &mdev_list);
mutex_unlock(&mdev_list_lock);

mdev->parent = parent;
kref_init(&mdev->ref);

mdev->dev.parent  = dev;
mdev->dev.bus     = &mdev_bus_type;
mdev->dev.release = mdev_device_release;
dev_set_name(&mdev->dev, "%pUl", uuid.b);

ret = device_register(&mdev->dev);
if (ret) {
put_device(&mdev->dev);
goto mdev_fail;
}

ret = mdev_device_create_ops(kobj, mdev);
if (ret)
goto create_fail;

ret = mdev_create_sysfs_files(&mdev->dev, type);
if (ret) {
mdev_device_remove_ops(mdev, true);
goto create_fail;
}

mdev->type_kobj = kobj;
mdev->active = true;
dev_dbg(&mdev->dev, "MDEV: created\n");

return 0;

create_fail:
device_unregister(&mdev->dev);
mdev_fail:
mdev_put_parent(parent);
return ret;
}

int mdev_device_remove(struct device *dev, bool force_remove)
{
struct mdev_device *mdev, *tmp;
struct mdev_parent *parent;
struct mdev_type *type;
int ret;

mdev = to_mdev_device(dev);

mutex_lock(&mdev_list_lock);
list_for_each_entry(tmp, &mdev_list, next) {
if (tmp == mdev)
break;
}

if (tmp != mdev) {
mutex_unlock(&mdev_list_lock);
return -ENODEV;
}

if (!mdev->active) {
mutex_unlock(&mdev_list_lock);
return -EAGAIN;
}

mdev->active = false;
mutex_unlock(&mdev_list_lock);

type = to_mdev_type(mdev->type_kobj);
parent = mdev->parent;

ret = mdev_device_remove_ops(mdev, force_remove);
if (ret) {
mdev->active = true;
return ret;
}

mdev_remove_sysfs_files(dev, type);
device_unregister(dev);
mdev_put_parent(parent);

return 0;
}

static int __init mdev_init(void)
{
return mdev_bus_register();
}

static void __exit mdev_exit(void)
{
if (mdev_bus_compat_class)
class_compat_unregister(mdev_bus_compat_class);

mdev_bus_unregister();
}

module_init(mdev_init)
module_exit(mdev_exit)

MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_SOFTDEP("post: vfio_mdev");



Хотя модуль vfio_mdev запустил без ошибок и в dmesg тоже тихо.