cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

io_ordering.txt (2963B)


      1Chinese translated version of Documentation/driver-api/io_ordering.rst
      2
      3If you have any comment or update to the content, please contact the
      4original document maintainer directly.  However, if you have a problem
      5communicating in English you can also ask the Chinese maintainer for
      6help.  Contact the Chinese maintainer if this translation is outdated
      7or if there is a problem with the translation.
      8
      9Chinese maintainer: Lin Yongting <linyongting@gmail.com>
     10---------------------------------------------------------------------
     11Documentation/driver-api/io_ordering.rst 的中文翻译
     12
     13如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
     14交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
     15译存在问题,请联系中文版维护者。
     16
     17中文版维护者: 林永听 Lin Yongting <linyongting@gmail.com>
     18中文版翻译者: 林永听 Lin Yongting <linyongting@gmail.com>
     19中文版校译者: 林永听 Lin Yongting <linyongting@gmail.com>
     20
     21
     22以下为正文
     23---------------------------------------------------------------------
     24
     25在某些平台上,所谓的内存映射I/O是弱顺序。在这些平台上,驱动开发者有责任
     26保证I/O内存映射地址的写操作按程序图意的顺序达到设备。通常读取一个“安全”
     27设备寄存器或桥寄存器,触发IO芯片清刷未处理的写操作到达设备后才处理读操作,
     28而达到保证目的。驱动程序通常在spinlock保护的临界区退出之前使用这种技术。
     29这也可以保证后面的写操作只在前面的写操作之后到达设备(这非常类似于内存
     30屏障操作,mb(),不过仅适用于I/O)。
     31
     32假设一个设备驱动程的具体例子:
     33
     34        ...
     35CPU A:  spin_lock_irqsave(&dev_lock, flags)
     36CPU A:  val = readl(my_status);
     37CPU A:  ...
     38CPU A:  writel(newval, ring_ptr);
     39CPU A:  spin_unlock_irqrestore(&dev_lock, flags)
     40        ...
     41CPU B:  spin_lock_irqsave(&dev_lock, flags)
     42CPU B:  val = readl(my_status);
     43CPU B:  ...
     44CPU B:  writel(newval2, ring_ptr);
     45CPU B:  spin_unlock_irqrestore(&dev_lock, flags)
     46        ...
     47
     48上述例子中,设备可能会先接收到newval2的值,然后接收到newval的值,问题就
     49发生了。不过很容易通过下面方法来修复:
     50
     51        ...
     52CPU A:  spin_lock_irqsave(&dev_lock, flags)
     53CPU A:  val = readl(my_status);
     54CPU A:  ...
     55CPU A:  writel(newval, ring_ptr);
     56CPU A:  (void)readl(safe_register); /* 配置寄存器?*/
     57CPU A:  spin_unlock_irqrestore(&dev_lock, flags)
     58        ...
     59CPU B:  spin_lock_irqsave(&dev_lock, flags)
     60CPU B:  val = readl(my_status);
     61CPU B:  ...
     62CPU B:  writel(newval2, ring_ptr);
     63CPU B:  (void)readl(safe_register); /* 配置寄存器?*/
     64CPU B:  spin_unlock_irqrestore(&dev_lock, flags)
     65
     66在解决方案中,读取safe_register寄存器,触发IO芯片清刷未处理的写操作,
     67再处理后面的读操作,防止引发数据不一致问题。