LINUX.ORG.RU

История изменений

Исправление red75prim, (текущая версия) :

А в чём проблема с 5-ю ансейфами? Можно сделать один большой на функцию, но лучше не от этого не будет. Unsafe обращает внимание на места, где легко всё сломать: например, поставим 4 вместо 2-х в pread, получим UB.

Хм… У них там и так UB, ioctl пишет в константный conf_reg. Видимо не было опыта работы с ioctl. Вот поэтому unsafe и полезен - нет опыта, пиши без unsafe. И это легко проверить грепом.

Код длинный, да. В основном потому, что с биндингами не заморачивались, всё на голом libc. С safe обёртками это выглядело бы как-то так:

pub fn vfio_enable_dma(device: &mut File) -> Result<(), Box<dyn Error>> {
    // Get region info for config region
    let conf_reg = unsafe { vfio_device_get_region_info(device, VFIO_PCI_CONFIG_REGION_INDEX)? };
    let command_register_offset = (conf_reg.offset + COMMAND_REGISTER_OFFSET) as i64;
    let mut dma = device.pread_u16(command_register_offset)?;
    dma |= 1 << BUS_MASTER_ENABLE_BIT;
    device.pwrite_u16(command_register_offset, dma)?;
    Ok(())
}

Исходная версия red75prim, :

А в чём проблема с 5-ю ансейфами? Можно сделать один большой на функцию, но лучше не от этого не будет. Unsafe обращает внимание на места, где легко всё сломать: например, поставим 4 вместо 2-х в pread, получим UB.

Хм… У них там и так UB, ioctl пишет в константный conf_reg. Видимо не было опыта работы с ioctl. Вот поэтому unsafe и полезен - нет опыта, пиши без unsafe. И это легко проверить грепом.

Код длинный, да. В основном потому, что с биндингами не заморачивались, всё на голом libc. С safe обёртками это выглядело бы как-то так:

pub fn vfio_enable_dma(device: &mut File) -> Result<(), Box<dyn Error>> {
    // Get region info for config region
    let conf_reg = vfio_device_get_region_info(device, VFIO_PCI_CONFIG_REGION_INDEX)?;
    let command_register_offset = (conf_reg.offset + COMMAND_REGISTER_OFFSET) as i64;
    let mut dma = device.pread_u16(command_register_offset)?;
    dma |= 1 << BUS_MASTER_ENABLE_BIT;
    device.pwrite_u16(command_register_offset, dma)?;
    Ok(())
}