Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
bc01b761
Commit
bc01b761
authored
Jun 21, 2021
by
Alex Williamson
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'hch-mdev-direct-v4' into v5.14/vfio/next
parents
3b62a624
681c1615
Changes
19
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
441 additions
and
409 deletions
+441
-409
Documentation/driver-api/vfio-mediated-device.rst
Documentation/driver-api/vfio-mediated-device.rst
+12
-23
Documentation/s390/vfio-ap.rst
Documentation/s390/vfio-ap.rst
+0
-1
arch/s390/Kconfig
arch/s390/Kconfig
+1
-1
drivers/base/base.h
drivers/base/base.h
+0
-1
drivers/base/bus.c
drivers/base/bus.c
+2
-6
drivers/base/dd.c
drivers/base/dd.c
+106
-86
drivers/gpu/drm/i915/Kconfig
drivers/gpu/drm/i915/Kconfig
+1
-1
drivers/vfio/mdev/Kconfig
drivers/vfio/mdev/Kconfig
+0
-7
drivers/vfio/mdev/Makefile
drivers/vfio/mdev/Makefile
+1
-2
drivers/vfio/mdev/mdev_core.c
drivers/vfio/mdev/mdev_core.c
+36
-10
drivers/vfio/mdev/mdev_driver.c
drivers/vfio/mdev/mdev_driver.c
+10
-0
drivers/vfio/mdev/mdev_private.h
drivers/vfio/mdev/mdev_private.h
+2
-0
drivers/vfio/mdev/vfio_mdev.c
drivers/vfio/mdev/vfio_mdev.c
+1
-23
include/linux/device.h
include/linux/device.h
+2
-0
include/linux/mdev.h
include/linux/mdev.h
+2
-0
samples/Kconfig
samples/Kconfig
+3
-3
samples/vfio-mdev/mbochs.c
samples/vfio-mdev/mbochs.c
+91
-72
samples/vfio-mdev/mdpy.c
samples/vfio-mdev/mdpy.c
+88
-71
samples/vfio-mdev/mtty.c
samples/vfio-mdev/mtty.c
+83
-102
No files found.
Documentation/driver-api/vfio-mediated-device.rst
View file @
bc01b761
...
...
@@ -93,7 +93,7 @@ interfaces:
Registration Interface for a Mediated Bus Driver
------------------------------------------------
The registration interface for a mediated
bus
driver provides the following
The registration interface for a mediated
device
driver provides the following
structure to represent a mediated device's driver::
/*
...
...
@@ -136,37 +136,26 @@ The structures in the mdev_parent_ops structure are as follows:
* dev_attr_groups: attributes of the parent device
* mdev_attr_groups: attributes of the mediated device
* supported_config: attributes to define supported configurations
* device_driver: device driver to bind for mediated device instances
The functions in the mdev_parent_ops structure are as follows:
The mdev_parent_ops also still has various functions pointers. Theses exist
for historical reasons only and shall not be used for new drivers.
* create: allocate basic resources in a driver for a mediated device
* remove: free resources in a driver when a mediated device is destroyed
(Note that mdev-core provides no implicit serialization of create/remove
callbacks per mdev parent device, per mdev type, or any other categorization.
Vendor drivers are expected to be fully asynchronous in this respect or
provide their own internal resource protection.)
The callbacks in the mdev_parent_ops structure are as follows:
* open: open callback of mediated device
* close: close callback of mediated device
* ioctl: ioctl callback of mediated device
* read : read emulation callback
* write: write emulation callback
* mmap: mmap emulation callback
A driver should use the mdev_parent_ops structure in the function call to
register itself with the mdev core driver::
When a driver wants to add the GUID creation sysfs to an existing device it has
probe'd to then it should call::
extern int mdev_register_device(struct device *dev,
const struct mdev_parent_ops *ops);
However, the mdev_parent_ops structure is not required in the function call
that a driver should use to unregister itself with the mdev core driver::
This will provide the 'mdev_supported_types/XX/create' files which can then be
used to trigger the creation of a mdev_device. The created mdev_device will be
attached to the specified driver.
When the driver needs to remove itself it calls::
extern void mdev_unregister_device(struct device *dev);
Which will unbind and destroy all the created mdevs and remove the sysfs files.
Mediated Device Management Interface Through sysfs
==================================================
...
...
Documentation/s390/vfio-ap.rst
View file @
bc01b761
...
...
@@ -514,7 +514,6 @@ These are the steps:
* S390_AP_IOMMU
* VFIO
* VFIO_MDEV
* VFIO_MDEV_DEVICE
* KVM
If using make menuconfig select the following to build the vfio_ap module::
...
...
arch/s390/Kconfig
View file @
bc01b761
...
...
@@ -768,7 +768,7 @@ config VFIO_CCW
config VFIO_AP
def_tristate n
prompt "VFIO support for AP devices"
depends on S390_AP_IOMMU && VFIO_MDEV
_DEVICE
&& KVM
depends on S390_AP_IOMMU && VFIO_MDEV && KVM
depends on ZCRYPT
help
This driver grants access to Adjunct Processor (AP) devices
...
...
drivers/base/base.h
View file @
bc01b761
...
...
@@ -152,7 +152,6 @@ extern int driver_add_groups(struct device_driver *drv,
const
struct
attribute_group
**
groups
);
extern
void
driver_remove_groups
(
struct
device_driver
*
drv
,
const
struct
attribute_group
**
groups
);
int
device_driver_attach
(
struct
device_driver
*
drv
,
struct
device
*
dev
);
void
device_driver_detach
(
struct
device
*
dev
);
extern
char
*
make_class_name
(
const
char
*
name
,
struct
kobject
*
kobj
);
...
...
drivers/base/bus.c
View file @
bc01b761
...
...
@@ -210,15 +210,11 @@ static ssize_t bind_store(struct device_driver *drv, const char *buf,
int
err
=
-
ENODEV
;
dev
=
bus_find_device_by_name
(
bus
,
NULL
,
buf
);
if
(
dev
&&
d
ev
->
driver
==
NULL
&&
d
river_match_device
(
drv
,
dev
))
{
if
(
dev
&&
driver_match_device
(
drv
,
dev
))
{
err
=
device_driver_attach
(
drv
,
dev
);
if
(
err
>
0
)
{
if
(
!
err
)
{
/* success */
err
=
count
;
}
else
if
(
err
==
0
)
{
/* driver didn't accept device */
err
=
-
ENODEV
;
}
}
put_device
(
dev
);
...
...
drivers/base/dd.c
View file @
bc01b761
...
...
@@ -471,6 +471,8 @@ static void driver_sysfs_remove(struct device *dev)
* (It is ok to call with no other effort from a driver's probe() method.)
*
* This function must be called with the device lock held.
*
* Callers should prefer to use device_driver_attach() instead.
*/
int
device_bind_driver
(
struct
device
*
dev
)
{
...
...
@@ -491,15 +493,6 @@ EXPORT_SYMBOL_GPL(device_bind_driver);
static
atomic_t
probe_count
=
ATOMIC_INIT
(
0
);
static
DECLARE_WAIT_QUEUE_HEAD
(
probe_waitqueue
);
static
void
driver_deferred_probe_add_trigger
(
struct
device
*
dev
,
int
local_trigger_count
)
{
driver_deferred_probe_add
(
dev
);
/* Did a trigger occur while probing? Need to re-trigger if yes */
if
(
local_trigger_count
!=
atomic_read
(
&
deferred_trigger_count
))
driver_deferred_probe_trigger
();
}
static
ssize_t
state_synced_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
...
...
@@ -513,12 +506,43 @@ static ssize_t state_synced_show(struct device *dev,
}
static
DEVICE_ATTR_RO
(
state_synced
);
static
int
call_driver_probe
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
int
ret
=
0
;
if
(
dev
->
bus
->
probe
)
ret
=
dev
->
bus
->
probe
(
dev
);
else
if
(
drv
->
probe
)
ret
=
drv
->
probe
(
dev
);
switch
(
ret
)
{
case
0
:
break
;
case
-
EPROBE_DEFER
:
/* Driver requested deferred probing */
dev_dbg
(
dev
,
"Driver %s requests probe deferral
\n
"
,
drv
->
name
);
break
;
case
-
ENODEV
:
case
-
ENXIO
:
pr_debug
(
"%s: probe of %s rejects match %d
\n
"
,
drv
->
name
,
dev_name
(
dev
),
ret
);
break
;
default:
/* driver matched but the probe failed */
pr_warn
(
"%s: probe of %s failed with error %d
\n
"
,
drv
->
name
,
dev_name
(
dev
),
ret
);
break
;
}
return
ret
;
}
static
int
really_probe
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
int
ret
=
-
EPROBE_DEFER
;
int
local_trigger_count
=
atomic_read
(
&
deferred_trigger_count
);
bool
test_remove
=
IS_ENABLED
(
CONFIG_DEBUG_TEST_DRIVER_REMOVE
)
&&
!
drv
->
suppress_bind_attrs
;
int
ret
;
if
(
defer_all_probes
)
{
/*
...
...
@@ -527,17 +551,13 @@ static int really_probe(struct device *dev, struct device_driver *drv)
* wait_for_device_probe() right after that to avoid any races.
*/
dev_dbg
(
dev
,
"Driver %s force probe deferral
\n
"
,
drv
->
name
);
driver_deferred_probe_add
(
dev
);
return
ret
;
return
-
EPROBE_DEFER
;
}
ret
=
device_links_check_suppliers
(
dev
);
if
(
ret
==
-
EPROBE_DEFER
)
driver_deferred_probe_add_trigger
(
dev
,
local_trigger_count
);
if
(
ret
)
return
ret
;
atomic_inc
(
&
probe_count
);
pr_debug
(
"bus: '%s': %s: probing driver %s with device %s
\n
"
,
drv
->
bus
->
name
,
__func__
,
drv
->
name
,
dev_name
(
dev
));
if
(
!
list_empty
(
&
dev
->
devres_head
))
{
...
...
@@ -572,14 +592,14 @@ static int really_probe(struct device *dev, struct device_driver *drv)
goto
probe_failed
;
}
if
(
dev
->
bus
->
probe
)
{
ret
=
dev
->
bus
->
probe
(
dev
);
if
(
ret
)
goto
probe_failed
;
}
else
if
(
drv
->
probe
)
{
ret
=
drv
->
probe
(
dev
);
if
(
ret
)
goto
probe_failed
;
ret
=
call_driver_probe
(
dev
,
drv
);
if
(
ret
)
{
/*
* Return probe errors as positive values so that the callers
* can distinguish them from other errors.
*/
ret
=
-
ret
;
goto
probe_failed
;
}
if
(
device_add_groups
(
dev
,
drv
->
dev_groups
))
{
...
...
@@ -621,7 +641,6 @@ static int really_probe(struct device *dev, struct device_driver *drv)
dev
->
pm_domain
->
sync
(
dev
);
driver_bound
(
dev
);
ret
=
1
;
pr_debug
(
"bus: '%s': %s: bound device %s to driver %s
\n
"
,
drv
->
bus
->
name
,
__func__
,
dev_name
(
dev
),
drv
->
name
);
goto
done
;
...
...
@@ -650,31 +669,7 @@ static int really_probe(struct device *dev, struct device_driver *drv)
dev
->
pm_domain
->
dismiss
(
dev
);
pm_runtime_reinit
(
dev
);
dev_pm_set_driver_flags
(
dev
,
0
);
switch
(
ret
)
{
case
-
EPROBE_DEFER
:
/* Driver requested deferred probing */
dev_dbg
(
dev
,
"Driver %s requests probe deferral
\n
"
,
drv
->
name
);
driver_deferred_probe_add_trigger
(
dev
,
local_trigger_count
);
break
;
case
-
ENODEV
:
case
-
ENXIO
:
pr_debug
(
"%s: probe of %s rejects match %d
\n
"
,
drv
->
name
,
dev_name
(
dev
),
ret
);
break
;
default:
/* driver matched but the probe failed */
pr_warn
(
"%s: probe of %s failed with error %d
\n
"
,
drv
->
name
,
dev_name
(
dev
),
ret
);
}
/*
* Ignore errors returned by ->probe so that the next driver can try
* its luck.
*/
ret
=
0
;
done:
atomic_dec
(
&
probe_count
);
wake_up_all
(
&
probe_waitqueue
);
return
ret
;
}
...
...
@@ -728,25 +723,14 @@ void wait_for_device_probe(void)
}
EXPORT_SYMBOL_GPL
(
wait_for_device_probe
);
/**
* driver_probe_device - attempt to bind device & driver together
* @drv: driver to bind a device to
* @dev: device to try to bind to the driver
*
* This function returns -ENODEV if the device is not registered,
* 1 if the device is bound successfully and 0 otherwise.
*
* This function must be called with @dev lock held. When called for a
* USB interface, @dev->parent lock must be held as well.
*
* If the device has a parent, runtime-resume the parent before driver probing.
*/
static
int
driver_probe_device
(
struct
device_driver
*
drv
,
struct
device
*
dev
)
static
int
__driver_probe_device
(
struct
device_driver
*
drv
,
struct
device
*
dev
)
{
int
ret
=
0
;
if
(
!
device_is_registered
(
dev
))
if
(
dev
->
p
->
dead
||
!
device_is_registered
(
dev
))
return
-
ENODEV
;
if
(
dev
->
driver
)
return
-
EBUSY
;
dev
->
can_match
=
true
;
pr_debug
(
"bus: '%s': %s: matched device %s with driver %s
\n
"
,
...
...
@@ -770,6 +754,42 @@ static int driver_probe_device(struct device_driver *drv, struct device *dev)
return
ret
;
}
/**
* driver_probe_device - attempt to bind device & driver together
* @drv: driver to bind a device to
* @dev: device to try to bind to the driver
*
* This function returns -ENODEV if the device is not registered, -EBUSY if it
* already has a driver, 0 if the device is bound successfully and a positive
* (inverted) error code for failures from the ->probe method.
*
* This function must be called with @dev lock held. When called for a
* USB interface, @dev->parent lock must be held as well.
*
* If the device has a parent, runtime-resume the parent before driver probing.
*/
static
int
driver_probe_device
(
struct
device_driver
*
drv
,
struct
device
*
dev
)
{
int
trigger_count
=
atomic_read
(
&
deferred_trigger_count
);
int
ret
;
atomic_inc
(
&
probe_count
);
ret
=
__driver_probe_device
(
drv
,
dev
);
if
(
ret
==
-
EPROBE_DEFER
||
ret
==
EPROBE_DEFER
)
{
driver_deferred_probe_add
(
dev
);
/*
* Did a trigger occur while probing? Need to re-trigger if yes
*/
if
(
trigger_count
!=
atomic_read
(
&
deferred_trigger_count
)
&&
!
defer_all_probes
)
driver_deferred_probe_trigger
();
}
atomic_dec
(
&
probe_count
);
wake_up_all
(
&
probe_waitqueue
);
return
ret
;
}
static
inline
bool
cmdline_requested_async_probing
(
const
char
*
drv_name
)
{
return
parse_option_str
(
async_probe_drv_names
,
drv_name
);
...
...
@@ -867,7 +887,14 @@ static int __device_attach_driver(struct device_driver *drv, void *_data)
if
(
data
->
check_async
&&
async_allowed
!=
data
->
want_async
)
return
0
;
return
driver_probe_device
(
drv
,
dev
);
/*
* Ignore errors returned by ->probe so that the next driver can try
* its luck.
*/
ret
=
driver_probe_device
(
drv
,
dev
);
if
(
ret
<
0
)
return
ret
;
return
ret
==
0
;
}
static
void
__device_attach_async_helper
(
void
*
_dev
,
async_cookie_t
cookie
)
...
...
@@ -1023,43 +1050,34 @@ static void __device_driver_unlock(struct device *dev, struct device *parent)
* @dev: Device to attach it to
*
* Manually attach driver to a device. Will acquire both @dev lock and
* @dev->parent lock if needed.
* @dev->parent lock if needed.
Returns 0 on success, -ERR on failure.
*/
int
device_driver_attach
(
struct
device_driver
*
drv
,
struct
device
*
dev
)
{
int
ret
=
0
;
int
ret
;
__device_driver_lock
(
dev
,
dev
->
parent
);
/*
* If device has been removed or someone has already successfully
* bound a driver before us just skip the driver probe call.
*/
if
(
!
dev
->
p
->
dead
&&
!
dev
->
driver
)
ret
=
driver_probe_device
(
drv
,
dev
);
ret
=
__driver_probe_device
(
drv
,
dev
);
__device_driver_unlock
(
dev
,
dev
->
parent
);
/* also return probe errors as normal negative errnos */
if
(
ret
>
0
)
ret
=
-
ret
;
if
(
ret
==
-
EPROBE_DEFER
)
return
-
EAGAIN
;
return
ret
;
}
EXPORT_SYMBOL_GPL
(
device_driver_attach
);
static
void
__driver_attach_async_helper
(
void
*
_dev
,
async_cookie_t
cookie
)
{
struct
device
*
dev
=
_dev
;
struct
device_driver
*
drv
;
int
ret
=
0
;
int
ret
;
__device_driver_lock
(
dev
,
dev
->
parent
);
drv
=
dev
->
p
->
async_driver
;
/*
* If device has been removed or someone has already successfully
* bound a driver before us just skip the driver probe call.
*/
if
(
!
dev
->
p
->
dead
&&
!
dev
->
driver
)
ret
=
driver_probe_device
(
drv
,
dev
);
ret
=
driver_probe_device
(
drv
,
dev
);
__device_driver_unlock
(
dev
,
dev
->
parent
);
dev_dbg
(
dev
,
"driver %s async attach completed: %d
\n
"
,
drv
->
name
,
ret
);
...
...
@@ -1114,7 +1132,9 @@ static int __driver_attach(struct device *dev, void *data)
return
0
;
}
device_driver_attach
(
drv
,
dev
);
__device_driver_lock
(
dev
,
dev
->
parent
);
driver_probe_device
(
drv
,
dev
);
__device_driver_unlock
(
dev
,
dev
->
parent
);
return
0
;
}
...
...
drivers/gpu/drm/i915/Kconfig
View file @
bc01b761
...
...
@@ -124,7 +124,7 @@ config DRM_I915_GVT_KVMGT
tristate "Enable KVM/VFIO support for Intel GVT-g"
depends on DRM_I915_GVT
depends on KVM
depends on VFIO_MDEV
&& VFIO_MDEV_DEVICE
depends on VFIO_MDEV
default n
help
Choose this option if you want to enable KVMGT support for
...
...
drivers/vfio/mdev/Kconfig
View file @
bc01b761
...
...
@@ -9,10 +9,3 @@ config VFIO_MDEV
See Documentation/driver-api/vfio-mediated-device.rst for more details.
If you don't know what do here, say N.
config VFIO_MDEV_DEVICE
tristate "VFIO driver for Mediated devices"
depends on VFIO && VFIO_MDEV
default n
help
VFIO based driver for Mediated devices.
drivers/vfio/mdev/Makefile
View file @
bc01b761
# SPDX-License-Identifier: GPL-2.0-only
mdev-y
:=
mdev_core.o mdev_sysfs.o mdev_driver.o
mdev-y
:=
mdev_core.o mdev_sysfs.o mdev_driver.o
vfio_mdev.o
obj-$(CONFIG_VFIO_MDEV)
+=
mdev.o
obj-$(CONFIG_VFIO_MDEV_DEVICE)
+=
vfio_mdev.o
drivers/vfio/mdev/mdev_core.c
View file @
bc01b761
...
...
@@ -94,9 +94,11 @@ static void mdev_device_remove_common(struct mdev_device *mdev)
mdev_remove_sysfs_files
(
mdev
);
device_del
(
&
mdev
->
dev
);
lockdep_assert_held
(
&
parent
->
unreg_sem
);
ret
=
parent
->
ops
->
remove
(
mdev
);
if
(
ret
)
dev_err
(
&
mdev
->
dev
,
"Remove failed: err=%d
\n
"
,
ret
);
if
(
parent
->
ops
->
remove
)
{
ret
=
parent
->
ops
->
remove
(
mdev
);
if
(
ret
)
dev_err
(
&
mdev
->
dev
,
"Remove failed: err=%d
\n
"
,
ret
);
}
/* Balances with device_initialize() */
put_device
(
&
mdev
->
dev
);
...
...
@@ -127,7 +129,9 @@ int mdev_register_device(struct device *dev, const struct mdev_parent_ops *ops)
char
*
envp
[]
=
{
env_string
,
NULL
};
/* check for mandatory ops */
if
(
!
ops
||
!
ops
->
create
||
!
ops
->
remove
||
!
ops
->
supported_type_groups
)
if
(
!
ops
||
!
ops
->
supported_type_groups
)
return
-
EINVAL
;
if
(
!
ops
->
device_driver
&&
(
!
ops
->
create
||
!
ops
->
remove
))
return
-
EINVAL
;
dev
=
get_device
(
dev
);
...
...
@@ -256,6 +260,7 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
int
ret
;
struct
mdev_device
*
mdev
,
*
tmp
;
struct
mdev_parent
*
parent
=
type
->
parent
;
struct
mdev_driver
*
drv
=
parent
->
ops
->
device_driver
;
mutex_lock
(
&
mdev_list_lock
);
...
...
@@ -296,14 +301,22 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
goto
out_put_device
;
}
ret
=
parent
->
ops
->
create
(
mdev
);
if
(
ret
)
goto
out_unlock
;
if
(
parent
->
ops
->
create
)
{
ret
=
parent
->
ops
->
create
(
mdev
);
if
(
ret
)
goto
out_unlock
;
}
ret
=
device_add
(
&
mdev
->
dev
);
if
(
ret
)
goto
out_remove
;
if
(
!
drv
)
drv
=
&
vfio_mdev_driver
;
ret
=
device_driver_attach
(
&
drv
->
driver
,
&
mdev
->
dev
);
if
(
ret
)
goto
out_del
;
ret
=
mdev_create_sysfs_files
(
mdev
);
if
(
ret
)
goto
out_del
;
...
...
@@ -317,7 +330,8 @@ int mdev_device_create(struct mdev_type *type, const guid_t *uuid)
out_del:
device_del
(
&
mdev
->
dev
);
out_remove:
parent
->
ops
->
remove
(
mdev
);
if
(
parent
->
ops
->
remove
)
parent
->
ops
->
remove
(
mdev
);
out_unlock:
up_read
(
&
parent
->
unreg_sem
);
out_put_device:
...
...
@@ -360,11 +374,24 @@ int mdev_device_remove(struct mdev_device *mdev)
static
int
__init
mdev_init
(
void
)
{
return
mdev_bus_register
();
int
rc
;
rc
=
mdev_bus_register
();
if
(
rc
)
return
rc
;
rc
=
mdev_register_driver
(
&
vfio_mdev_driver
);
if
(
rc
)
goto
err_bus
;
return
0
;
err_bus:
mdev_bus_unregister
();
return
rc
;
}
static
void
__exit
mdev_exit
(
void
)
{
mdev_unregister_driver
(
&
vfio_mdev_driver
);
if
(
mdev_bus_compat_class
)
class_compat_unregister
(
mdev_bus_compat_class
);
...
...
@@ -378,4 +405,3 @@ MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_SOFTDEP
(
"post: vfio_mdev"
);
drivers/vfio/mdev/mdev_driver.c
View file @
bc01b761
...
...
@@ -71,10 +71,20 @@ static int mdev_remove(struct device *dev)
return
0
;
}
static
int
mdev_match
(
struct
device
*
dev
,
struct
device_driver
*
drv
)
{
/*
* No drivers automatically match. Drivers are only bound by explicit
* device_driver_attach()
*/
return
0
;
}
struct
bus_type
mdev_bus_type
=
{
.
name
=
"mdev"
,
.
probe
=
mdev_probe
,
.
remove
=
mdev_remove
,
.
match
=
mdev_match
,
};
EXPORT_SYMBOL_GPL
(
mdev_bus_type
);
...
...
drivers/vfio/mdev/mdev_private.h
View file @
bc01b761
...
...
@@ -37,6 +37,8 @@ struct mdev_type {
#define to_mdev_type(_kobj) \
container_of(_kobj, struct mdev_type, kobj)
extern
struct
mdev_driver
vfio_mdev_driver
;
int
parent_create_sysfs_files
(
struct
mdev_parent
*
parent
);
void
parent_remove_sysfs_files
(
struct
mdev_parent
*
parent
);
...
...
drivers/vfio/mdev/vfio_mdev.c
View file @
bc01b761
...
...
@@ -17,10 +17,6 @@
#include "mdev_private.h"
#define DRIVER_VERSION "0.1"
#define DRIVER_AUTHOR "NVIDIA Corporation"
#define DRIVER_DESC "VFIO based driver for Mediated device"
static
int
vfio_mdev_open
(
struct
vfio_device
*
core_vdev
)
{
struct
mdev_device
*
mdev
=
to_mdev_device
(
core_vdev
->
dev
);
...
...
@@ -140,7 +136,7 @@ static void vfio_mdev_remove(struct mdev_device *mdev)
kfree
(
vdev
);
}
st
atic
st
ruct
mdev_driver
vfio_mdev_driver
=
{
struct
mdev_driver
vfio_mdev_driver
=
{
.
driver
=
{
.
name
=
"vfio_mdev"
,
.
owner
=
THIS_MODULE
,
...
...
@@ -149,21 +145,3 @@ static struct mdev_driver vfio_mdev_driver = {
.
probe
=
vfio_mdev_probe
,
.
remove
=
vfio_mdev_remove
,
};
static
int
__init
vfio_mdev_init
(
void
)
{
return
mdev_register_driver
(
&
vfio_mdev_driver
);
}
static
void
__exit
vfio_mdev_exit
(
void
)
{
mdev_unregister_driver
(
&
vfio_mdev_driver
);
}
module_init
(
vfio_mdev_init
)
module_exit
(
vfio_mdev_exit
)
MODULE_VERSION
(
DRIVER_VERSION
);
MODULE_LICENSE
(
"GPL v2"
);
MODULE_AUTHOR
(
DRIVER_AUTHOR
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
include/linux/device.h
View file @
bc01b761
...
...
@@ -845,6 +845,8 @@ static inline void *dev_get_platdata(const struct device *dev)
* Manual binding of a device to driver. See drivers/base/bus.c
* for information on use.
*/
int
__must_check
device_driver_attach
(
struct
device_driver
*
drv
,
struct
device
*
dev
);
int
__must_check
device_bind_driver
(
struct
device
*
dev
);
void
device_release_driver
(
struct
device
*
dev
);
int
__must_check
device_attach
(
struct
device
*
dev
);
...
...
include/linux/mdev.h
View file @
bc01b761
...
...
@@ -55,6 +55,7 @@ struct device *mtype_get_parent_dev(struct mdev_type *mtype);
* register the device to mdev module.
*
* @owner: The module owner.
* @device_driver: Which device driver to probe() on newly created devices
* @dev_attr_groups: Attributes of the parent device.
* @mdev_attr_groups: Attributes of the mediated device.
* @supported_type_groups: Attributes to define supported types. It is mandatory
...
...
@@ -103,6 +104,7 @@ struct device *mtype_get_parent_dev(struct mdev_type *mtype);
**/
struct
mdev_parent_ops
{
struct
module
*
owner
;
struct
mdev_driver
*
device_driver
;
const
struct
attribute_group
**
dev_attr_groups
;
const
struct
attribute_group
**
mdev_attr_groups
;
struct
attribute_group
**
supported_type_groups
;
...
...
samples/Kconfig
View file @
bc01b761
...
...
@@ -154,14 +154,14 @@ config SAMPLE_UHID
config SAMPLE_VFIO_MDEV_MTTY
tristate "Build VFIO mtty example mediated device sample code -- loadable modules only"
depends on VFIO_MDEV
_DEVICE
&& m
depends on VFIO_MDEV && m
help
Build a virtual tty sample driver for use as a VFIO
mediated device
config SAMPLE_VFIO_MDEV_MDPY
tristate "Build VFIO mdpy example mediated device sample code -- loadable modules only"
depends on VFIO_MDEV
_DEVICE
&& m
depends on VFIO_MDEV && m
help
Build a virtual display sample driver for use as a VFIO
mediated device. It is a simple framebuffer and supports
...
...
@@ -178,7 +178,7 @@ config SAMPLE_VFIO_MDEV_MDPY_FB
config SAMPLE_VFIO_MDEV_MBOCHS
tristate "Build VFIO mdpy example mediated device sample code -- loadable modules only"
depends on VFIO_MDEV
_DEVICE
&& m
depends on VFIO_MDEV && m
select DMA_SHARED_BUFFER
help
Build a virtual display sample driver for use as a VFIO
...
...
samples/vfio-mdev/mbochs.c
View file @
bc01b761
This diff is collapsed.
Click to expand it.
samples/vfio-mdev/mdpy.c
View file @
bc01b761
This diff is collapsed.
Click to expand it.
samples/vfio-mdev/mtty.c
View file @
bc01b761
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment