设备虚拟化基础 - PCI

pci_bus_read_config_dword实现说明 在学习linux 内核启动pci总线枚举的过程中,发现跟踪到底层扫描总线上每个设备,是通过读取每个设备的vendor id来确定设备的有无,在这里遇到了一个问题,就是函数pci_bus_read_config_dword没有找到实现,只是找到了EXPORT_SYMBOL(pci_bus_read_config_dword),没有具体的实现,仔细看了一下access.c文件才发现这个问题所在,先贴出 阅读详情

目录

1. 配置空间概念和作用

2. 通过配置空间发现设备

3. Linux读取PCI配置空间接口

4. 内核中具体读取配置空间实例

5. Virtion设备自定义空间

6. Linux读取Capabilities List代码解析


1. 配置空间概念和作用

详细的定义可以参考PCI Spec的第六章《Configuration Space》中的描述,这里仅摘抄关键点

  • 所有的PCI设备必须实现配置空间,配置空间的本质是一堆寄存器。
  • 配置空间可以用来发现设备
  • pci local bus spec规定的配置空间最大256字节,前64字节是spec中定义好的,称预定义空间,其中前16字节对所有类型的pci设备都相同(是指格式,而不其中具体的值),之后的空间格式因类型而不同,对前16字节空间,我称它为通用配置空间。

 上面是摘自PCI3.0规范的配置空间,一共64字节,即预定义空间,其中前16字节对应通用配置空间。

预定义空间解析

vendor id:厂商ID,用来标识pci设备出自哪个厂商,这里是0x1af4,来自Red Hat。
device id:厂商下的产品ID,传统virtio-blk设备,这里是0x1001
revision id:厂商决定是否使用,设备版本ID,这里未使用
header type:pci设备类型,0x00(普通设备),0x01(pci bridge),0x02(CardBus bridge)。virtio是普通设备,这里是0x00

status: 描述pci设备状态的寄存器

 其中有一位是Capabilities List,它是pci规范定义的附加空间标志位,Capabilities List的意义是允许在pci设备配置空间之后加上额外的寄存器,这些寄存器由Capability List组织起来,用来实现特定的功能,附加空间在64字节配置空间之后,最大不能超过256字节。以virtio-blk为例,它标记了这个位,因此在virtio-blk设备配置空间之后,还有一段空间用来实现virtio-blk的一些特有功能。1表示capabilities pointer字段(0x34)存放了附加寄存器组的起始地址。这里的地址表示附加空间在pci设备空间内的偏移。具体Capability List怎么理解本文后面分析。

2. 通过配置空间发现设备

发下设备需要确定两个事情:PCI设备地址,以及确定地址之后具体怎么通过该地址访问。

PCI设备地址 : 参考PCI规范3.2.2.3.2章节

设备地址可以通过Bus号,Device号,功能号和寄存器号唯一确定:

 

 Linux内核中确定该地址可以通过宏:

/*
 * Functions for accessing PCI base (first 256 bytes) and extended
 * (4096 bytes per PCI function) configuration space with type 1
 * accesses.
 */

#define PCI_CONF1_ADDRESS(bus, devfn, reg) \
	(0x80000000 | ((reg & 0xF00) << 16) | (bus << 16) \
	| (devfn << 8) | (reg & 0xFC))

访问配置空间

  • 配置空间寄存器偏移

PCI_CONF1_ADDRES宏确定了配置空间的基地址(Base Address),还要结合配置空间偏移具体访问具体的功能,比如访问配置空间的Command对应的offset:04h,Capabilities pointer偏移:0x34h。

  • 端口访问

配置空间地址无法直接访问,需要通过特定的端口来访问:

CONFIG_ADDRESS(CF8h) : 将需要访问的配置空间地址设置到该端口

CONFIG_DATA(CFCh):从该端口读取配置空间的值。

3. Linux读取PCI配置空间接口
//参数dev : pci 设备
//where : 配置空间寄存器对应的偏移offset
int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val);
int pci_read_config_word(const struct pci_dev *dev, int where, u16 *val);
int pci_read_config_dword(const struct pci_dev *dev, int where, u32 *val);
int pci_write_config_byte(const struct pci_dev *dev, int where, u8 val);
int pci_write_config_word(const struct pci_dev *dev, int where, u16 val);
int pci_write_config_dword(const struct pci_dev *dev, int where, u32 val);

上面API实现路径:drivers/pci/access.c

int pci_read_config_byte(const struct pci_dev *dev, int where, u8 *val)                                                                                                  
{
    if (pci_dev_is_disconnected(dev)) {
        *val = ~0;
        return PCIBIOS_DEVICE_NOT_FOUND;
    }
    return pci_bus_read_config_byte(dev->bus, dev->devfn, where, val);
}

上面已pci_read_config_byte为例:我们知道要读取配置空间必须通过CONFIG_ADDRESS,地址需要bus number, device number, function number和offset,这些值通过dev和where获取,可以想象pci_bus_read_config_byte最终应该也是要调用out汇编指令访问CONFIG_DDRESS端口,层层跟进最终调用到如下函数:

arch/x86/pci/direct.c

#define PCI_CONF1_ADDRESS(bus, devfn, reg) \
    (0x80000000 | ((reg & 0xF00) << 16) | (bus << 16) \
    | (devfn << 8) | (reg & 0xFC))

static int pci_conf1_read(unsigned int seg, unsigned int bus,
              unsigned int devfn, int reg, int len, u32 *value)
{
    unsigned long flags;

    if (seg || (bus > 255) || (devfn > 255) || (reg > 4095)) {
        *value = -1;
        return -EINVAL;
    }

    raw_spin_lock_irqsave(&pci_config_lock, flags);

    outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);

    switch (len) {
    case 1:
        *value = inb(0xCFC + (reg & 3));
        break;
    case 2:
        *value = inw(0xCFC + (reg & 2));
        break;
    case 4:
        *value = inl(0xCFC);
        break;
    }

    raw_spin_unlock_irqrestore(&pci_config_lock, flags);

    return 0;
}
4. Linux内核中具体读取配置空间实例
static void __iomem *map_capability(struct pci_dev *dev, int off,
				    size_t minlen,
				    u32 align,
				    u32 start, u32 size,
				    size_t *len)
{
	u8 bar;
	u32 offset, length;
	void __iomem *p;

	pci_read_config_byte(dev, off + offsetof(struct virtio_pci_cap,
						 bar),
			     &bar);
	pci_read_config_dword(dev, off + offsetof(struct virtio_pci_cap, offset),
			     &offset);
	pci_read_config_dword(dev, off + offsetof(struct virtio_pci_cap, length),
			      &length);
    ...
}

这里off对应每个capbility的offset(具体怎么理解参见本文下面capbility相关章节),每个capbility用struct virtio_pci_cap结构体描述:

/* This is the PCI capability header: */
struct virtio_pci_cap {
    __u8 cap_vndr;      /* Generic PCI field: PCI_CAP_ID_VNDR */
    __u8 cap_next;      /* Generic PCI field: next ptr. */
    __u8 cap_len;       /* Generic PCI field: capability length */
    __u8 cfg_type;      /* Identifies the structure. */
    __u8 bar;       /* Where to find it. */
    __u8 padding[3];    /* Pad to full dword. */
    __le32 offset;      /* Offset within bar. */
    __le32 length;      /* Length of the structure, in bytes. */
};
5. Virtion设备自定义空间

每个PCI具有不同的功能和配置,所以除了64字节的预定义空间之外,每个PCI设备可以自定义配置空间,配置设备的能力,pci spec规范中有个很重要的Capabilities List概念,即设备的能力列表。有几个重要的问题:

5.1. 能力列表的位置(地址)

        还记着预定义配置空间中有个Capability list么,这里面存储的就是能力列表的位置(offset)。

5.2 . 能力列表项格式

/* This is the PCI capability header: */
struct virtio_pci_cap {
    __u8 cap_vndr;      /* Generic PCI field: PCI_CAP_ID_VNDR */
    __u8 cap_next;      /* Generic PCI field: next ptr. */
    __u8 cap_len;       /* Generic PCI field: capability length */
    __u8 cfg_type;      /* Identifies the structure. */
    __u8 bar;       /* Where to find it. */
    __u8 padding[3];    /* Pad to full dword. */
    __le32 offset;      /* Offset within bar. */
    __le32 length;      /* Length of the structure, in bytes. */
};

vndr :capability类型,取值可参考pci spec H附录:

next:表示下一个capability在pci配置空间的位置

len:capability这个数据结构的长度

type : 取值范围如下

 Capabilities List图示:

在这里插入图片描述

                                                                (引用自参考文章)

6. Linux读取Capabilities List代码解析

drivers/virtio/virtio_pci_modern.c:

/* the PCI probing function */
int virtio_pci_modern_probe(struct virtio_pci_device *vp_dev)
{
    struct pci_dev *pci_dev = vp_dev->pci_dev;
    int err, common, isr, notify, device;
    u32 notify_length;
    u32 notify_offset;

    check_offsets();

    /* We only own devices >= 0x1000 and <= 0x107f: leave the rest. */
    if (pci_dev->device < 0x1000 || pci_dev->device > 0x107f)
        return -ENODEV;

    if (pci_dev->device < 0x1040) {
        /* Transitional devices: use the PCI subsystem device id as
         * virtio device id, same as legacy driver always did.
         */
        vp_dev->vdev.id.device = pci_dev->subsystem_device;
    } else {
        /* Modern devices: simply use PCI device id, but start from 0x1040. */
        vp_dev->vdev.id.device = pci_dev->device - 0x1040;
    }
    vp_dev->vdev.id.vendor = pci_dev->subsystem_vendor;

    /* check for a common config: if not, use legacy mode (bar 0). */
    //遍历配置空间的Capabilities List列表,查找是否存在VIRTIO_PCI_CAP_COMMON_CFG这种
    //Type类型的能力。
    common = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_COMMON_CFG,
                        IORESOURCE_IO | IORESOURCE_MEM,
                        &vp_dev->modern_bars);
    if (!common) {
        dev_info(&pci_dev->dev,
             "virtio_pci: leaving for legacy driver\n");
        return -ENODEV;
    }

    /* If common is there, these should be too... */
    isr = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_ISR_CFG,
                     IORESOURCE_IO | IORESOURCE_MEM,
                     &vp_dev->modern_bars);
    notify = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_NOTIFY_CFG,
                        IORESOURCE_IO | IORESOURCE_MEM,
                        &vp_dev->modern_bars);
    if (!isr || !notify) {
        dev_err(&pci_dev->dev,
            "virtio_pci: missing capabilities %i/%i/%i\n",
            common, isr, notify);
        return -EINVAL;
    }

    err = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(64));
    if (err)
        err = dma_set_mask_and_coherent(&pci_dev->dev,
                        DMA_BIT_MASK(32));
    if (err)
        dev_warn(&pci_dev->dev, "Failed to enable 64-bit or 32-bit DMA.  Trying to continue, but this might not work.\n");

    /* Device capability is only mandatory for devices that have
     * device-specific configuration.
     */
    device = virtio_pci_find_capability(pci_dev, VIRTIO_PCI_CAP_DEVICE_CFG,
                        IORESOURCE_IO | IORESOURCE_MEM,
                        &vp_dev->modern_bars);

    err = pci_request_selected_regions(pci_dev, vp_dev->modern_bars,
                       "virtio-pci-modern");
    if (err)
        return err;

    err = -EINVAL;
    vp_dev->common = map_capability(pci_dev, common,
                    sizeof(struct virtio_pci_common_cfg), 4,
                    0, sizeof(struct virtio_pci_common_cfg),
                    NULL);
    if (!vp_dev->common)
        goto err_map_common;
    vp_dev->isr = map_capability(pci_dev, isr, sizeof(u8), 1,
                     0, 1,
                     NULL);
    if (!vp_dev->isr)
        goto err_map_isr;

    /* Read notify_off_multiplier from config space. */
    pci_read_config_dword(pci_dev,
                  notify + offsetof(struct virtio_pci_notify_cap,
                        notify_off_multiplier),
                  &vp_dev->notify_offset_multiplier);
    /* Read notify length and offset from config space. */
    pci_read_config_dword(pci_dev,
                  notify + offsetof(struct virtio_pci_notify_cap,
                        cap.length),
                  &notify_length);

    pci_read_config_dword(pci_dev,
                  notify + offsetof(struct virtio_pci_notify_cap,
                        cap.offset),
                  &notify_offset);

    /* We don't know how many VQs we'll map, ahead of the time.
     * If notify length is small, map it all now.
     * Otherwise, map each VQ individually later.
     */
    if ((u64)notify_length + (notify_offset % PAGE_SIZE) <= PAGE_SIZE) {
        vp_dev->notify_base = map_capability(pci_dev, notify, 2, 2,
                             0, notify_length,
                             &vp_dev->notify_len);
        if (!vp_dev->notify_base)
            goto err_map_notify;
    } else {
        vp_dev->notify_map_cap = notify;
    }

    /* Again, we don't know how much we should map, but PAGE_SIZE
     * is more than enough for all existing devices.
     */
    if (device) {
        vp_dev->device = map_capability(pci_dev, device, 0, 4,
                        0, PAGE_SIZE,
                        &vp_dev->device_len);
        if (!vp_dev->device)
            goto err_map_device;

        vp_dev->vdev.config = &virtio_pci_config_ops;
    } else {
        vp_dev->vdev.config = &virtio_pci_config_nodev_ops;
    }

    vp_dev->config_vector = vp_config_vector;
    vp_dev->setup_vq = setup_vq;
    vp_dev->del_vq = del_vq;

    return 0;
    ...
    return err;
}

probe函数连续调用virtio_pci_find_capability通过遍历Capabilities List查找PCI设备是否存其第二个参数指定的能力,第二个参数对应virtio_pci_cap结构体中的cfg_type。

static inline int virtio_pci_find_capability(struct pci_dev *dev, u8 cfg_type,
					     u32 ioresource_types, int *bars)
{
	int pos;

	for (pos = pci_find_capability(dev, PCI_CAP_ID_VNDR);
	     pos > 0;
	     pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_VNDR)) {
		u8 type, bar;
		pci_read_config_byte(dev, pos + offsetof(struct virtio_pci_cap,
							 cfg_type),
				     &type);
		pci_read_config_byte(dev, pos + offsetof(struct virtio_pci_cap,
							 bar),
				     &bar);

		/* Ignore structures with reserved BAR values */
		if (bar > 0x5)
			continue;

		if (type == cfg_type) {
			if (pci_resource_len(dev, bar) &&
			    pci_resource_flags(dev, bar) & ioresource_types) {
				*bars |= (1 << bar);
				return pos;
			}
		}
	}
	return 0;
}

pci_find_capability :返回Capabilities List列表中的一个能力pos (配置空间的offset),其内部是通过配置空间的34h偏移处的Capabilities Pointer确定的。

/**
 * pci_find_capability - query for devices' capabilities
 * @dev: PCI device to query
 * @cap: capability code
 *
 * Tell if a device supports a given PCI capability.
 * Returns the address of the requested capability structure within the
 * device's PCI configuration space or 0 in case the device does not
 * support it.  Possible values for @cap:
 *
 *  %PCI_CAP_ID_PM           Power Management
 *  %PCI_CAP_ID_AGP          Accelerated Graphics Port
 *  %PCI_CAP_ID_VPD          Vital Product Data
 *  %PCI_CAP_ID_SLOTID       Slot Identification
 *  %PCI_CAP_ID_MSI          Message Signalled Interrupts
 *  %PCI_CAP_ID_CHSWP        CompactPCI HotSwap
 *  %PCI_CAP_ID_PCIX         PCI-X
 *  %PCI_CAP_ID_EXP          PCI Express
 */
int pci_find_capability(struct pci_dev *dev, int cap)
{
    int pos;

    //pos值是配置空间对应的Capabilities Pointer的offset,即0x34h
    pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);

    //如果开启了Capabilities List功能,__pci_find_nex_cap找到0x34H处对应的能力的pos
    //如果是第一次查找,以5.2中图为例,__pci_find_next_cap返回的是第一个能力的pos 0x98
    if (pos)
        pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap);

    return pos;
}

static int __pci_bus_find_cap_start(struct pci_bus *bus,                                                                                                                 
                    unsigned int devfn, u8 hdr_type)
{
    u16 status;

    pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
    if (!(status & PCI_STATUS_CAP_LIST))
        return 0;

    switch (hdr_type) {
    case PCI_HEADER_TYPE_NORMAL:
    case PCI_HEADER_TYPE_BRIDGE:
        return PCI_CAPABILITY_LIST; //宏的值为0x34h
    case PCI_HEADER_TYPE_CARDBUS:
        return PCI_CB_CAPABILITY_LIST;
    }

    return 0;
}

static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
                   u8 pos, int cap, int *ttl)
{
    u8 id;
    u16 ent;

    pci_bus_read_config_byte(bus, devfn, pos, &pos);

    while ((*ttl)--) {
        if (pos < 0x40)
            break;
        pos &= ~3;
        pci_bus_read_config_word(bus, devfn, pos, &ent);

        id = ent & 0xff;
        if (id == 0xff)
            break;
        if (id == cap)
            return pos;
        pos = (ent >> 8);
    }
    return 0;
}

参考文章:

https://blog.youkuaiyun.com/fouweng/article/details/62890979

VirtIO实现原理——PCI基础_virtio-pci_享乐主的博客-优快云博客

深入QEMU设备模型:从PCIe看门狗实例看MDEV/IOMMU虚拟化基石 本文深入解析QEMU设备模型,以PCIe看门狗实例为基础,探讨MDEV/IOMMU虚拟化技术的实现机制。通过分析QEMU的类型系统、PCI配置空间模拟及BAR空间管理,揭示现代虚拟化场景中设备直通和中介设备的核心原理,为开发者提供设备调试与测试的实用技巧。 阅读详情

相关推荐

从零到一:在openEuler上构建高效虚拟化环境的全流程解析

本文详细解析了在openEuler操作系统上构建高效虚拟化环境的全流程,包括基础组件安装、网络配置、性能调优等关键步骤。重点介绍了libvirt工具集的使用方法,以及如何利用openEuler的CCA安全特性和PCI直通技术提升虚拟化性能,为企业级应用提供稳定可靠的虚拟化解决方案。

weixin_29268267的博客 567

通用PCIe-AI加速卡与虚拟化技术

PCIE设备虚拟化直通技术

LazyCaaat 1893

pcie虚拟网卡实现的几种方案

基于pcie链路,实现虚拟网卡,从而使用socket进行通信。以下是四种实现方案:

ARM-Linux 2349

PCIE SRIOV虚拟化技术

介绍PCIE SRIOV技术

MQWYY3的博客 5294

KVMTOOL: PCI设备的模拟

在 KVMTOOL 中对于PCI 设备的模拟,每个 virtio 后端驱动都会有如下类似这样的调用来初始化后端,例如virtio-vsock:virtio_vsock_init_one ->virtio_init -> virtio_pci__init(vdev->ops->init)。virtio_pci__init 函数就是在模拟一个PCI 设备的配置空间。 int virtio_pci__init(struct kvm *kvm, void *dev, struct ...

yiyeguzhou100的专栏 2366

21、VMDirectPath I/O与存储虚拟化设备(SVDs)全解析

本文深入解析了VMDirectPath I/O与存储虚拟化设备(SVDs)的技术原理、配置方法及实际应用场景。涵盖VM配置文件修改、vSphere环境下的直通设置、SVD的工作机制与架构限制,并提供部署建议与未来发展趋势。帮助读者全面掌握两种关键技术在虚拟化基础设施中的应用,提升性能与管理效率。

j0k1l2m3n的博客 53

Linux PCI设备扫描全解析:从BIOS到内核的完整流程与实战调试技巧

本文深入解析Linux系统中PCI设备从BIOS到内核的完整扫描流程,涵盖PCI架构基础、BIOS初始化、内核PCI子系统初始化及资源分配机制。通过实战调试技巧和工具介绍,帮助开发者高效排查PCI设备问题,优化扫描性能,并处理虚拟化与嵌入式环境中的特殊场景。

weixin_26908317的博客 374

Pcileech(DMA)开源项目简述

希望大DMA家能正确认识FPGA,正确使用DMA技术,对于市场上各类伪装成花里胡哨设备的FPGA板卡它的本质是不会变的,不要上当受骗。

2301_79773847的博客 5959

Libvirt项目中的主机设备管理技术详解

Libvirt作为一款强大的虚拟化管理工具,提供了对物理和虚拟主机设备的全面管理能力。本文将深入解析Libvirt如何管理USB、PCI、SCSI和网络设备等主机设备,以及如何利用这些设备提供的虚拟化功能,如SR-IOV、NPIV、MDEV和DRM等。 ## 设备管理基础 Libvirt通过节点设备驱动(node device driver)提供了一系列管理功能: 1. **设备列表与信息查...

gitblog_01159的博客 392

MOSS-TTS开源语音合成家族:从架构解析到生产部署实战

语音合成(TTS)技术旨在让计算机将文本转换为自然流畅的语音,其核心原理通常涉及文本分析、声学模型和声码器等模块。近年来,基于深度学习的端到端TTS模型,特别是结合残差向量量化(RVQ)和Transformer架构的方案,显著提升了合成语音的自然度和效率。这类技术的价值在于能够广泛应用于有声内容创作、智能助手、无障碍服务以及实时交互等场景。本文聚焦于开源的MOSS-TTS家族,它通过模块化设计,针对高保真合成、多角色对话、实时交互等不同需求提供了专用模型。文章深入解析了其底层的Delay与Local两种架构

weixin_28745565的博客 419

【通信协议】I2C总线(一主多从)

I2C总线(一主多从)之软件模拟代码详解

m0_75090944的博客 9838

关于Linux虚拟化技术KVM的科普 科普二(KVM虚拟机代码揭秘)

代码分析文章《KVM虚拟机代码揭秘——QEMU代码结构分析》、《KVM虚拟机代码揭秘——中断虚拟化》、《KVM虚拟机代码揭秘——设备IO虚拟化》、《KVM虚拟机代码揭秘——QEMU的PCI总线与设备(上)》、《KVM虚拟机代码揭秘——QEMU的PCI总线与设备(下)》。先从大的方面分析代码结构,然后分中断、IO、PCI总线与设备详细介绍。 KVM虚拟机代码揭秘——QEMU代码结构分析 关于TC...

weixin_30791095的博客 141

最新小旋风蜘蛛池X6.21解密版+绕过授权带教程

介绍: 1.站群管理:用你的域名在这里添加网站 2.站点优化:站点互链,内容优化 2.系统设置:开启蜘蛛池 3.采集管理(可开启自动采集) 4.缓存设置:推荐开启tkd缓存 其他的用户根据自己的实际情况后台进行配置,通常以下: 1.后台首页(这里显示系统的大致概况) 2.系统设置:蜘蛛池的基本设置(访问开关、跳转、统计等等) 3.站群管理: 1.网站管理(用你的域名在这里添加网站) 2.模型管理(可构建不同类型站点:电影、文章、论坛等等) 3.TKDB调用模板(即:title、keywords、descri

百度SEO程序下载 2935

Linux设备驱动终极指南:从零开始掌握5.10内核驱动开发

想要深入Linux内核世界,却苦于找不到合适的学习资源?Linux-Device-Driver项目为你打开了一扇通往**Linux设备驱动开发**殿堂的大门。这个专门针对**5.10内核版本**设计的开源项目,通过精心编排的示例代码,让初学者也能轻松入门驱动开发。 ## 为什么选择这个Linux设备驱动学习项目? ### 现代化内核支持 🚀 与传统的驱动开发教程不同,这个项目完全基于Lin

gitblog_00525的博客 791

Exposure Fusion

MertensTMO原理详解: 文章:2007年Exposure Fusion 论文链接:http://ntp-0.cs.ucl.ac.uk/staff/j.kautz/publications/exposure_fusion.pdf 论文代码:C版本:https://github.com/JawThrow/ExposureFusion python版本:https://github.com/lzocro/Exposure-Fusion matlab版本:https://github.com/Mericam

大长腿不解释 1652

IEEE S&P 2026 大模型安全论文整理

本文梳理了 IEEE S&P 2026(第47届 IEEE 安全与隐私研讨会)中与 LLM Safety 相关的论文,涵盖大模型越狱攻击、防御与对齐、隐私保护、RAG 安全、多模态大模型安全、智能体安全、图-LLM 安全、工具链安全及生成式 AI 安全与隐私等方向。

CSPhD-winston的博客 1331

【亲测免费】 探秘Linux设备驱动:深入浅出Linux-Device-Driver开源项目

在开源的世界里,每一次探索都是一场知识的盛宴。今天,我们聚焦于一个面向Linux内核5.10版本的开源宝藏——**Linux-Device-Driver**。这个项目不仅为学习和研究Linux设备驱动提供了宝贵的资源,还巧妙地衔接了经典与现代,让古老的知识焕发新生。 ## 项目介绍 Linux-Device-Driver仓库是一扇通向Linux设备驱动世界的窗口,它特别适用于那些希望深入了解内...

gitblog_00091的博客 821

Ut接口原理及 VoLTE 补充业务自管理信令流程(GBA 引导认证+业务访问认证+ VoLTE 补充业务自管理)

2. Ut 接口及 VoLTE 业务子管理概述 2.1 UT 接口 —— VoLTE 终端补充业务配置 2.2终端通过 Ut 接口完成 VoLTE 补充业务自管理举例 2.3什么是 GBA 和 GAA 架构 2.4为什么要引入 GBA 架构认证及 BSF 网元 2.5UE(终端) 接口相关网元及功能 2.6GBA 架构流程概述 3. Ut 接口业务自管理信令流程 3.1 补充业务自管理及本文主要参考以下规范 3.2 Ut 接口业务自管理信令流程:查询补充业务 3.2.1 UE获

原来45的博客 1256

VIRTIO-Virtual IO Based On VPP/DPDK at front

VIRTIO前端驱动在VPP/DPDK上的应用及实现

fdasasfasfdasf的博客 662

FC7300 SPI MCAL配置引导

Example - QMI8A01z外设:Example - QMI8A01z外设:

舊梦的博客 257

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

VFIO代码分析(1)VFIO基本框架

·VFIO是一个用户态驱动框架,它利用硬件层面的IO虚拟化技术,将设备直通给虚拟机上。VFIO将物理设备上的资源(设备的配置空间,BAR空间,中断等)分解,并提供接口导出到用户空间,QEMU等用户层软件可以利用这些接口来获取硬件的资源。 这里仅介绍PCI设备对应的VFIO框架图。 其中: (1)VFIO API接口用于向应用层导出接口,QEMU等用户程序可以通过相应的ioctl与VFIO进行交互; (2)VFIO IOMMU接口调用IOMMU驱动接口,作DMA重映...

flyingnosky的专栏 4773

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

SR-IOV技术

SR-IOV(Single Root I/O Virtualization)是一个由PCI-SIG(PCI Special Interest Group)制定的规范,它允许一个PCIe设备在硬件层面上被划分为多个虚拟设备,以便多个虚拟机能够直接访问同一个物理设备,从而提高I/O性能和减少虚拟化开销。SR-IOV主要应用于网络适配器(NIC)和存储适配器等高性能I/O设备。通过SR-IOV技术,可以显著提升虚拟机的I/O性能和资源利用率,是实现高性能虚拟化解决方案的重要手段。

weixin_48579910的博客 1170

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Linux内核中的KVM虚拟化详解

KVM是一种基于硬件辅助虚拟化的虚拟化技术,它将Linux内核转变为一个 hypervisor。

jiang_style的博客 1021

PCIe体系结构介绍

PCI总线作为处理器系统的局部总线,主要目的是为了连接外部设备,而不是作为处理器的系统总线连接Cache和主存储器 PXI 规范是CompactPCI规范的扩展 ,面向仪器系统的PCI扩展 PCI Express的接口根据总线位宽不同而有所差异,包括X1、X4、X8以及X16。较短的PCI Express卡可以插入较长的PCI Express插槽中使用。 第I篇 PCI体系结构概述 第1章PCI总线的基本知识 PCI Express总线简称为PCIe总线,PCI-to-PCI...

flyingleo1981的专栏 8076

终极虚拟化性能优化指南:基于virtio协议的Windows驱动架构深度解析

在虚拟化环境中,性能优化是提升用户体验的关键。**kvm-guest-drivers-windows** 项目提供了基于 virtio 协议的 Windows 半虚拟化驱动,通过优化虚拟机与宿主机之间的通信,显著提升磁盘、网络等设备的性能。本文将深入解析该驱动架构的核心优势、组件构成及部署方法,帮助用户快速掌握虚拟化性能调优的实用技巧。 ## 为什么选择 virtio 驱动?揭秘性能提升的核心原

gitblog_00339的博客 464

KVM 介绍(1):简介及安装

学习 KVM 的系列文章: (1)介绍和安装 (2)CPU 和 内存虚拟化 (3)I/O QEMU 全虚拟化和准虚拟化(Para-virtulizaiton) (4)I/O PCI/PCIe设备直接分配和 SR-IOV (5)libvirt 介绍 (6)Nova 通过 libvirt 管理 QEMU/KVM 虚机 (7)快照 (snapshot) (...

weixin_33847182的博客 111
上一篇: 从源码角度看Linux进程组和线程组
下一篇: 新文件创建inode分配路径
OS技术解密
博客等级 码龄16年 3760粉丝 189原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值