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 (2980B)


      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
      9Traditional Chinese maintainer: Hu Haowen <src.res@email.cn>
     10---------------------------------------------------------------------
     11Documentation/driver-api/io_ordering.rst 的繁體中文翻譯
     12
     13如果想評論或更新本文的內容,請直接聯繫原文檔的維護者。如果你使用英文
     14交流有困難的話,也可以向繁體中文版維護者求助。如果本翻譯更新不及時或
     15者翻譯存在問題,請聯繫繁體中文版維護者。
     16
     17繁體中文版維護者: 胡皓文 Hu Haowen <src.res@email.cn>
     18繁體中文版翻譯者: 胡皓文 Hu Haowen <src.res@email.cn>
     19繁體中文版校譯者: 胡皓文 Hu Haowen <src.res@email.cn>
     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再處理後面的讀操作,防止引發數據不一致問題。
     68