Index: sys/compat/linuxkpi/common/include/linux/virtio.h =================================================================== --- /dev/null +++ sys/compat/linuxkpi/common/include/linux/virtio.h @@ -0,0 +1,90 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright 2021 Alex Richardson + * + * This work was supported by Innovate UK project 105694, "Digital Security by + * Design (DSbD) Technology Platform Prototype". + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#ifndef __LKPI_LINUX_VIRTIO_H +#define __LKPI_LINUX_VIRTIO_H + +#include + +#include +#include +#include +#include +#include + +struct linux_virtio_device; + +struct bsd_virtqueue; + +struct linux_virtqueue { + struct linux_virtio_device *vdev; + struct bsd_virtqueue *bsdq; + void *priv; +}; + +struct linux_virtio_device { + struct device dev; + device_t bsddev; + void *priv; +}; + +static inline struct linux_virtio_device * +dev_to_virtio(struct device *d) +{ + return container_of(d, struct linux_virtio_device, dev); +} + +/* + * The Linux and FreeBSD virtio function names partially overlap. To perform the + * API translation we have to namespace the functions and types. + */ +#ifndef __DO_NOT_DEFINE_LINUX_VIRTIO_NAMES +#define virtqueue linux_virtqueue +#define virtio_device linux_virtio_device +/* Rename the symbol to the linuxkpi name using asm() */ +#define VIRTIO_NAMESPACED_FN(ret, name, args) \ + ret name args __asm__(__XSTRING(__CONCAT(linux_, name))) +#else +#define VIRTIO_NAMESPACED_FN(ret, name, args) ret __CONCAT(linux_, name) args +#endif + +VIRTIO_NAMESPACED_FN(int, virtqueue_add_sgs, + (struct linux_virtqueue * vq, struct scatterlist *sgs[], + unsigned int out_sgs, unsigned int in_sgs, void *data, gfp_t gfp)); +VIRTIO_NAMESPACED_FN(void, virtqueue_disable_cb, (struct linux_virtqueue * vq)); +VIRTIO_NAMESPACED_FN(bool, virtqueue_enable_cb, (struct linux_virtqueue * vq)); +VIRTIO_NAMESPACED_FN(void *, virtqueue_get_buf, + (struct linux_virtqueue * vq, unsigned int *len)); +VIRTIO_NAMESPACED_FN(bool, virtqueue_kick, (struct linux_virtqueue * vq)); +VIRTIO_NAMESPACED_FN(bool, virtqueue_kick_prepare, + (struct linux_virtqueue * vq)); +VIRTIO_NAMESPACED_FN(bool, virtqueue_notify, (struct linux_virtqueue * vq)); +VIRTIO_NAMESPACED_FN(unsigned, virtqueue_num_free, (struct linux_virtqueue * vq)); + +#endif /* __LKPI_LINUX_VIRTIO_H */ Index: sys/compat/linuxkpi/common/include/linux/virtio_config.h =================================================================== --- /dev/null +++ sys/compat/linuxkpi/common/include/linux/virtio_config.h @@ -0,0 +1,94 @@ +/*- +* SPDX-License-Identifier: BSD-2-Clause +* +* Copyright 2021 Alex Richardson +* +* This work was supported by Innovate UK project 105694, "Digital Security by +* Design (DSbD) Technology Platform Prototype". +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +*/ +#ifndef __LKPI_LINUX_VIRTIO_CONFIG_H +#define __LKPI_LINUX_VIRTIO_CONFIG_H + +#include + +#ifndef __DO_NOT_DEFINE_LINUX_VIRTIO_NAMES +/* Virtio-gpu needs this defined in the Linux way (bit index not mask). */ +#define VIRTIO_F_VERSION_1 32 +#endif + + +typedef void(vq_callback_t)(struct linux_virtqueue *); + +VIRTIO_NAMESPACED_FN(bool, virtio_has_feature, + (const struct linux_virtio_device *vdev, unsigned int fbit)); +VIRTIO_NAMESPACED_FN(bool, virtio_has_iommu_quirk, + (const struct linux_virtio_device *vdev)); + +VIRTIO_NAMESPACED_FN(uint8_t, virtio_cread8, + (struct linux_virtio_device * vdev, unsigned int offset)); +VIRTIO_NAMESPACED_FN(uint16_t, virtio_cread16, + (struct linux_virtio_device * vdev, unsigned int offset)); +VIRTIO_NAMESPACED_FN(uint32_t, virtio_cread32, + (struct linux_virtio_device * vdev, unsigned int offset)); +VIRTIO_NAMESPACED_FN(uint64_t, virtio_cread64, + (struct linux_virtio_device * vdev, unsigned int offset)); +VIRTIO_NAMESPACED_FN(void, virtio_cwrite8, + (struct linux_virtio_device * vdev, unsigned int offset, uint8_t val)); +VIRTIO_NAMESPACED_FN(void, virtio_cwrite16, + (struct linux_virtio_device * vdev, unsigned int offset, uint16_t val)); +VIRTIO_NAMESPACED_FN(void, virtio_cwrite32, + (struct linux_virtio_device * vdev, unsigned int offset, uint32_t val)); +VIRTIO_NAMESPACED_FN(void, virtio_cwrite64, + (struct linux_virtio_device * vdev, unsigned int offset, uint64_t val)); + +/* + * virtio_cwrite_bytes() doesn't seem to exist in Linux, but it makes it a lot + * easier to implement virtio_cwrite(). + */ +VIRTIO_NAMESPACED_FN(void, virtio_cread_bytes, + (struct linux_virtio_device * vdev, unsigned offset, void *buf, + unsigned len)); +VIRTIO_NAMESPACED_FN(void, virtio_cwrite_bytes, + (struct linux_virtio_device * vdev, unsigned offset, const void *buf, + unsigned len)); + +struct irq_affinity; +VIRTIO_NAMESPACED_FN(int, virtio_find_vqs, + (struct linux_virtio_device * vdev, unsigned nvqs, struct linux_virtqueue *vqs[], + vq_callback_t *callbacks[], const char *const names[], + struct irq_affinity *desc)); +VIRTIO_NAMESPACED_FN(void, virtio_del_vqs, (struct linux_virtio_device *vdev)); +VIRTIO_NAMESPACED_FN(void, virtio_reset, (struct linux_virtio_device *vdev)); +VIRTIO_NAMESPACED_FN(void, virtio_device_ready, (struct linux_virtio_device *dev)); + +/* Simple implementation of virtio_cread/virtio_cwrite without type checks. */ +#define virtio_cread(vdev, structname, member, ptr) \ + virtio_cread_bytes(vdev, offsetof(structname, member), ptr, \ + sizeof(*ptr)) +#define virtio_cwrite(vdev, structname, member, ptr) \ + virtio_cwrite_bytes(vdev, offsetof(structname, member), ptr, \ + sizeof(*ptr)) + +#endif /* __LKPI_LINUX_VIRTIO_CONFIG_H */ + Index: sys/compat/linuxkpi/common/include/linux/virtio_gpu.h =================================================================== --- /dev/null +++ sys/compat/linuxkpi/common/include/linux/virtio_gpu.h @@ -0,0 +1,343 @@ +/* + * Virtio GPU Device + * + * Copyright Red Hat, Inc. 2013-2014 + * + * Authors: + * Dave Airlie + * Gerd Hoffmann + * + * This header is BSD licensed so anyone can use the definitions + * to implement compatible drivers/servers: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IBM OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __LKPI_LINUX_VIRTIO_GPU_H +#define __LKPI_LINUX_VIRTIO_GPU_H + +#include + +/* + * VIRTIO_GPU_CMD_CTX_* + * VIRTIO_GPU_CMD_*_3D + */ +#define VIRTIO_GPU_F_VIRGL 0 + +/* + * VIRTIO_GPU_CMD_GET_EDID + */ +#define VIRTIO_GPU_F_EDID 1 + +enum virtio_gpu_ctrl_type { + VIRTIO_GPU_UNDEFINED = 0, + + /* 2d commands */ + VIRTIO_GPU_CMD_GET_DISPLAY_INFO = 0x0100, + VIRTIO_GPU_CMD_RESOURCE_CREATE_2D, + VIRTIO_GPU_CMD_RESOURCE_UNREF, + VIRTIO_GPU_CMD_SET_SCANOUT, + VIRTIO_GPU_CMD_RESOURCE_FLUSH, + VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D, + VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING, + VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING, + VIRTIO_GPU_CMD_GET_CAPSET_INFO, + VIRTIO_GPU_CMD_GET_CAPSET, + VIRTIO_GPU_CMD_GET_EDID, + + /* 3d commands */ + VIRTIO_GPU_CMD_CTX_CREATE = 0x0200, + VIRTIO_GPU_CMD_CTX_DESTROY, + VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE, + VIRTIO_GPU_CMD_CTX_DETACH_RESOURCE, + VIRTIO_GPU_CMD_RESOURCE_CREATE_3D, + VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D, + VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D, + VIRTIO_GPU_CMD_SUBMIT_3D, + + /* cursor commands */ + VIRTIO_GPU_CMD_UPDATE_CURSOR = 0x0300, + VIRTIO_GPU_CMD_MOVE_CURSOR, + + /* success responses */ + VIRTIO_GPU_RESP_OK_NODATA = 0x1100, + VIRTIO_GPU_RESP_OK_DISPLAY_INFO, + VIRTIO_GPU_RESP_OK_CAPSET_INFO, + VIRTIO_GPU_RESP_OK_CAPSET, + VIRTIO_GPU_RESP_OK_EDID, + + /* error responses */ + VIRTIO_GPU_RESP_ERR_UNSPEC = 0x1200, + VIRTIO_GPU_RESP_ERR_OUT_OF_MEMORY, + VIRTIO_GPU_RESP_ERR_INVALID_SCANOUT_ID, + VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID, + VIRTIO_GPU_RESP_ERR_INVALID_CONTEXT_ID, + VIRTIO_GPU_RESP_ERR_INVALID_PARAMETER, +}; + +#define VIRTIO_GPU_FLAG_FENCE (1 << 0) + +struct virtio_gpu_ctrl_hdr { + __le32 type; + __le32 flags; + __le64 fence_id; + __le32 ctx_id; + __le32 padding; +}; + +/* data passed in the cursor vq */ + +struct virtio_gpu_cursor_pos { + __le32 scanout_id; + __le32 x; + __le32 y; + __le32 padding; +}; + +/* VIRTIO_GPU_CMD_UPDATE_CURSOR, VIRTIO_GPU_CMD_MOVE_CURSOR */ +struct virtio_gpu_update_cursor { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_cursor_pos pos; /* update & move */ + __le32 resource_id; /* update only */ + __le32 hot_x; /* update only */ + __le32 hot_y; /* update only */ + __le32 padding; +}; + +/* data passed in the control vq, 2d related */ + +struct virtio_gpu_rect { + __le32 x; + __le32 y; + __le32 width; + __le32 height; +}; + +/* VIRTIO_GPU_CMD_RESOURCE_UNREF */ +struct virtio_gpu_resource_unref { + struct virtio_gpu_ctrl_hdr hdr; + __le32 resource_id; + __le32 padding; +}; + +/* VIRTIO_GPU_CMD_RESOURCE_CREATE_2D: create a 2d resource with a format */ +struct virtio_gpu_resource_create_2d { + struct virtio_gpu_ctrl_hdr hdr; + __le32 resource_id; + __le32 format; + __le32 width; + __le32 height; +}; + +/* VIRTIO_GPU_CMD_SET_SCANOUT */ +struct virtio_gpu_set_scanout { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_rect r; + __le32 scanout_id; + __le32 resource_id; +}; + +/* VIRTIO_GPU_CMD_RESOURCE_FLUSH */ +struct virtio_gpu_resource_flush { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_rect r; + __le32 resource_id; + __le32 padding; +}; + +/* VIRTIO_GPU_CMD_TRANSFER_TO_HOST_2D: simple transfer to_host */ +struct virtio_gpu_transfer_to_host_2d { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_rect r; + __le64 offset; + __le32 resource_id; + __le32 padding; +}; + +struct virtio_gpu_mem_entry { + __le64 addr; + __le32 length; + __le32 padding; +}; + +/* VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING */ +struct virtio_gpu_resource_attach_backing { + struct virtio_gpu_ctrl_hdr hdr; + __le32 resource_id; + __le32 nr_entries; +}; + +/* VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING */ +struct virtio_gpu_resource_detach_backing { + struct virtio_gpu_ctrl_hdr hdr; + __le32 resource_id; + __le32 padding; +}; + +/* VIRTIO_GPU_RESP_OK_DISPLAY_INFO */ +#define VIRTIO_GPU_MAX_SCANOUTS 16 +struct virtio_gpu_resp_display_info { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_display_one { + struct virtio_gpu_rect r; + __le32 enabled; + __le32 flags; + } pmodes[VIRTIO_GPU_MAX_SCANOUTS]; +}; + +/* data passed in the control vq, 3d related */ + +struct virtio_gpu_box { + __le32 x, y, z; + __le32 w, h, d; +}; + +/* VIRTIO_GPU_CMD_TRANSFER_TO_HOST_3D, VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D */ +struct virtio_gpu_transfer_host_3d { + struct virtio_gpu_ctrl_hdr hdr; + struct virtio_gpu_box box; + __le64 offset; + __le32 resource_id; + __le32 level; + __le32 stride; + __le32 layer_stride; +}; + +/* VIRTIO_GPU_CMD_RESOURCE_CREATE_3D */ +#define VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP (1 << 0) +struct virtio_gpu_resource_create_3d { + struct virtio_gpu_ctrl_hdr hdr; + __le32 resource_id; + __le32 target; + __le32 format; + __le32 bind; + __le32 width; + __le32 height; + __le32 depth; + __le32 array_size; + __le32 last_level; + __le32 nr_samples; + __le32 flags; + __le32 padding; +}; + +/* VIRTIO_GPU_CMD_CTX_CREATE */ +struct virtio_gpu_ctx_create { + struct virtio_gpu_ctrl_hdr hdr; + __le32 nlen; + __le32 padding; + char debug_name[64]; +}; + +/* VIRTIO_GPU_CMD_CTX_DESTROY */ +struct virtio_gpu_ctx_destroy { + struct virtio_gpu_ctrl_hdr hdr; +}; + +/* VIRTIO_GPU_CMD_CTX_ATTACH_RESOURCE, VIRTIO_GPU_CMD_CTX_DETACH_RESOURCE */ +struct virtio_gpu_ctx_resource { + struct virtio_gpu_ctrl_hdr hdr; + __le32 resource_id; + __le32 padding; +}; + +/* VIRTIO_GPU_CMD_SUBMIT_3D */ +struct virtio_gpu_cmd_submit { + struct virtio_gpu_ctrl_hdr hdr; + __le32 size; + __le32 padding; +}; + +#define VIRTIO_GPU_CAPSET_VIRGL 1 +#define VIRTIO_GPU_CAPSET_VIRGL2 2 + +/* VIRTIO_GPU_CMD_GET_CAPSET_INFO */ +struct virtio_gpu_get_capset_info { + struct virtio_gpu_ctrl_hdr hdr; + __le32 capset_index; + __le32 padding; +}; + +/* VIRTIO_GPU_RESP_OK_CAPSET_INFO */ +struct virtio_gpu_resp_capset_info { + struct virtio_gpu_ctrl_hdr hdr; + __le32 capset_id; + __le32 capset_max_version; + __le32 capset_max_size; + __le32 padding; +}; + +/* VIRTIO_GPU_CMD_GET_CAPSET */ +struct virtio_gpu_get_capset { + struct virtio_gpu_ctrl_hdr hdr; + __le32 capset_id; + __le32 capset_version; +}; + +/* VIRTIO_GPU_RESP_OK_CAPSET */ +struct virtio_gpu_resp_capset { + struct virtio_gpu_ctrl_hdr hdr; + __u8 capset_data[]; +}; + +/* VIRTIO_GPU_CMD_GET_EDID */ +struct virtio_gpu_cmd_get_edid { + struct virtio_gpu_ctrl_hdr hdr; + __le32 scanout; + __le32 padding; +}; + +/* VIRTIO_GPU_RESP_OK_EDID */ +struct virtio_gpu_resp_edid { + struct virtio_gpu_ctrl_hdr hdr; + __le32 size; + __le32 padding; + __u8 edid[1024]; +}; + +#define VIRTIO_GPU_EVENT_DISPLAY (1 << 0) + +struct virtio_gpu_config { + __u32 events_read; + __u32 events_clear; + __u32 num_scanouts; + __u32 num_capsets; +}; + +/* simple formats for fbcon/X use */ +enum virtio_gpu_formats { + VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM = 1, + VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM = 2, + VIRTIO_GPU_FORMAT_A8R8G8B8_UNORM = 3, + VIRTIO_GPU_FORMAT_X8R8G8B8_UNORM = 4, + + VIRTIO_GPU_FORMAT_R8G8B8A8_UNORM = 67, + VIRTIO_GPU_FORMAT_X8B8G8R8_UNORM = 68, + + VIRTIO_GPU_FORMAT_A8B8G8R8_UNORM = 121, + VIRTIO_GPU_FORMAT_R8G8B8X8_UNORM = 134, +}; + +#endif Index: sys/compat/linuxkpi/common/include/linux/virtio_ids.h =================================================================== --- /dev/null +++ sys/compat/linuxkpi/common/include/linux/virtio_ids.h @@ -0,0 +1,34 @@ +/*- +* SPDX-License-Identifier: BSD-2-Clause +* +* Copyright 2021 Alex Richardson +* +* This work was supported by Innovate UK project 105694, "Digital Security by +* Design (DSbD) Technology Platform Prototype". +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +*/ +/* + * The in-tree virtio_ids.h header is a copy of the Linux one, so we can + * just forward to that one. + */ +#include Index: sys/compat/linuxkpi/common/include/linux/virtio_ring.h =================================================================== --- /dev/null +++ sys/compat/linuxkpi/common/include/linux/virtio_ring.h @@ -0,0 +1,34 @@ +/*- +* SPDX-License-Identifier: BSD-2-Clause +* +* Copyright 2021 Alex Richardson +* +* This work was supported by Innovate UK project 105694, "Digital Security by +* Design (DSbD) Technology Platform Prototype". +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +*/ +/* + * The in-tree virtio_ring.h header is a copy of the Linux one, so we can + * just forward to that one. + */ +#include Index: sys/compat/linuxkpi/common/include/linux/virtio_types.h =================================================================== --- /dev/null +++ sys/compat/linuxkpi/common/include/linux/virtio_types.h @@ -0,0 +1,46 @@ +#ifndef __LKPI_LINUX_VIRTIO_TYPES_H +#define __LKPI_LINUX_VIRTIO_TYPES_H +/* Type definitions for virtio implementations. + * + * This header is BSD licensed so anyone can use the definitions to implement + * compatible drivers/servers. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of IBM nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Copyright (C) 2014 Red Hat, Inc. + * Author: Michael S. Tsirkin + */ +#include + +/* + * __virtio{16,32,64} have the following meaning: + * - __u{16,32,64} for virtio devices in legacy mode, accessed in native endian + * - __le{16,32,64} for standard-compliant virtio devices + */ + +typedef __u16 __bitwise __virtio16; +typedef __u32 __bitwise __virtio32; +typedef __u64 __bitwise __virtio64; + +#endif /* __LKPI_LINUX_VIRTIO_TYPES_H */ Index: sys/compat/linuxkpi/common/src/linux_virtio.c =================================================================== --- /dev/null +++ sys/compat/linuxkpi/common/src/linux_virtio.c @@ -0,0 +1,208 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright 2021 Alex Richardson + * + * This work was supported by Innovate UK project 105694, "Digital Security by + * Design (DSbD) Technology Platform Prototype". + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include +#include +#include +#include +#include + +/* Not strictly necessary, but explicit names make mistakes less likely. */ +#define virtqueue bsd_virtqueue +#include +#include + +#define __DO_NOT_DEFINE_LINUX_VIRTIO_NAMES +#include +#include +#include + +static inline struct bsd_virtqueue * +linux_to_bsd_virtqueue(struct linux_virtqueue *vq) +{ + return vq->bsdq; +} + +int +linux_virtqueue_add_sgs(struct linux_virtqueue *vq, struct scatterlist *sgs[], + unsigned int out_sgs, unsigned int in_sgs, void *data, gfp_t gfp) +{ + struct sglist *native_sg; + size_t total_sgs = out_sgs + in_sgs; + int err; + + /* convert to a native sglist and then call virtqueue_enqueue(). */ + native_sg = sglist_alloc(total_sgs, gfp); + if (!native_sg) + return (-ENOMEM); + for (size_t i = 0; i < total_sgs; i++) { + struct scatterlist *sg = sgs[i]; + KASSERT(sg_is_last(sg), ("Unexpected chain in sglist %p", sg)); + err = sglist_append(native_sg, sg_virt(sg), sg->length); + if (err) + return -err; + } + err = virtqueue_enqueue(linux_to_bsd_virtqueue(vq), data, native_sg, + out_sgs, in_sgs); + return (err == 0 ? 0 : -err); +} + +void +linux_virtqueue_disable_cb(struct linux_virtqueue *vq) +{ + virtqueue_disable_intr(linux_to_bsd_virtqueue(vq)); +} + +bool +linux_virtqueue_enable_cb(struct linux_virtqueue *vq) +{ + /* FIXME: is this the correct return value? */ + return (!virtqueue_enable_intr(linux_to_bsd_virtqueue(vq))); +} +void * +linux_virtqueue_get_buf(struct linux_virtqueue *vq, unsigned int *len) +{ + return (virtqueue_poll(linux_to_bsd_virtqueue(vq), len)); +} + +unsigned +linux_virtqueue_num_free(struct linux_virtqueue *vq) +{ + return (virtqueue_nfree(linux_to_bsd_virtqueue(vq))); +} + +/* + * In Linux virtqueue_notify() is the lower-level API and virtqueue_kick() + * maps to FreeBSD virtqueue_notify(). + */ +bool +linux_virtqueue_kick(struct linux_virtqueue *vq) +{ + return (virtqueue_notify(linux_to_bsd_virtqueue(vq))); +} + +bool +linux_virtqueue_kick_prepare(struct linux_virtqueue *vq) +{ + return (vq_ring_must_notify_host(linux_to_bsd_virtqueue(vq))); +} + +bool linux_virtqueue_notify(struct linux_virtqueue *vq) { + return (vq_ring_notify_host(linux_to_bsd_virtqueue(vq))); +} + +bool +linux_virtio_has_feature(const struct linux_virtio_device *vdev, + unsigned int fbit) +{ + return (virtio_with_feature(vdev->bsddev, UINT64_C(1) << fbit)); +} + +bool +linux_virtio_has_iommu_quirk(const struct linux_virtio_device *vdev) +{ + return (!virtio_with_feature(vdev->bsddev, VIRTIO_F_IOMMU_PLATFORM)); +} + +/* Inlined device specific read/write functions for common lengths. */ +#define VIRTIO_RDWR_DEVICE_CONFIG(size, type) \ + type linux_virtio_cread##size(struct linux_virtio_device *vdev, \ + unsigned int offset) \ + { \ + type val; \ + virtio_read_device_config(vdev->bsddev, offset, &val, \ + sizeof(type)); \ + return (val); \ + } \ + \ + void linux_virtio_cwrite##size(struct linux_virtio_device *vdev, \ + unsigned int offset, type val) \ + { \ + virtio_write_device_config(vdev->bsddev, offset, &val, \ + sizeof(type)); \ + } + +VIRTIO_RDWR_DEVICE_CONFIG(8, uint8_t) +VIRTIO_RDWR_DEVICE_CONFIG(16, uint16_t) +VIRTIO_RDWR_DEVICE_CONFIG(32, uint32_t) +VIRTIO_RDWR_DEVICE_CONFIG(64, uint64_t) +#undef VIRTIO_RDWR_DEVICE_CONFIG + +void +linux_virtio_cread_bytes(struct linux_virtio_device *vdev, unsigned offset, + void *buf, unsigned len) +{ + virtio_read_device_config(vdev->bsddev, offset, buf, len); +} + +void +linux_virtio_cwrite_bytes(struct linux_virtio_device *vdev, unsigned offset, + const void *buf, unsigned len) +{ + virtio_write_device_config(vdev->bsddev, offset, buf, len); +} + +int +linux_virtio_find_vqs(struct linux_virtio_device *vdev, unsigned nvqs, + struct linux_virtqueue *vqs[], vq_callback_t *callbacks[], + const char *const names[], struct irq_affinity *desc) +{ + struct vq_alloc_info *info; + int error; + + info = malloc(sizeof(struct vq_alloc_info) * nvqs, M_TEMP, M_NOWAIT); + if (info == NULL) + return (-ENOMEM); + + for (unsigned i = 0; i < nvqs; i++) { + VQ_ALLOC_INFO_INIT(&info[i], 0, (virtqueue_intr_t*)callbacks[i], + vqs[i], &vqs[i]->bsdq, "%s", names[i]); + } + + error = virtio_alloc_virtqueues(vdev->bsddev, 0, nvqs, info); + free(info, M_TEMP); + return (error == 0 ? 0 : -error); +} + +void linux_virtio_device_ready(struct linux_virtio_device *dev) +{ + virtio_reinit_complete(dev->bsddev); +} + +void linux_virtio_reset(struct linux_virtio_device *dev) +{ + panic("%s not implemented!", __func__); +} + +void linux_virtio_del_vqs(struct linux_virtio_device *dev) +{ + panic("%s not implemented!", __func__); +} + +MODULE_DEPEND(linuxkpi, virtio, 1, 1, 1); Index: sys/conf/files =================================================================== --- sys/conf/files +++ sys/conf/files @@ -4591,6 +4591,8 @@ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_usb.c optional compat_linuxkpi usb \ compile-with "${LINUXKPI_C}" +compat/linuxkpi/common/src/linux_virtio.c optional compat_linuxkpi virtio \ + compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_work.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_xarray.c optional compat_linuxkpi \ Index: sys/modules/linuxkpi/Makefile =================================================================== --- sys/modules/linuxkpi/Makefile +++ sys/modules/linuxkpi/Makefile @@ -26,6 +26,7 @@ linux_slab.c \ linux_tasklet.c \ linux_usb.c \ + linux_virtio.c \ linux_work.c \ linux_xarray.c