daily pastebin goal
16%
SHARE
TWEET

ZenBridgeBaconRecovery rev1

a guest Jan 3rd, 2018 520 in 136 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2.  * This program is free software: you can redistribute it and/or modify
  3.  * it under the terms of the GNU General Public License as published by
  4.  * the Free Software Foundation, version 3 of the License.
  5.  *
  6.  * This program is distributed in the hope that it will be useful,
  7.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.  * GNU General Public License for more details.
  10.  *
  11.  * You should have received a copy of the GNU General Public License
  12.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  13.  */
  14.  
  15. import java.io.File;
  16. import java.io.FileInputStream;
  17. import java.io.FileOutputStream;
  18. import java.io.IOException;
  19. import java.nio.file.Path;
  20. import java.util.Date;
  21. import java.util.HashMap;
  22. import java.util.Map.Entry;
  23.  
  24. /**
  25.  * Try to recover Zen's PCIe bridge after a secondary bus
  26.  * reset kicks it out of whack.
  27.  *
  28.  * @author HyenaCheeseHeads
  29.  */
  30. public class ZenBridgeBaconRecovery {
  31.     public static void log(String text){
  32.         System.out.println(new Date() + ": "+text);
  33.     }
  34.    
  35.     public static void main(String[] args) throws IOException, InterruptedException {        
  36.         System.out.println("-------------------------------------------");
  37.         System.out.println("Zen PCIe-Bridge BAR/Config Recovery Tool, rev 1, 2018, HyenaCheeseHeads");
  38.         System.out.println("-------------------------------------------");
  39.         HashMap<Path, Path> bridgeMapping = new HashMap<>();
  40.        
  41.         File vfioDir = new File("/sys/bus/pci/drivers/vfio-pci");
  42.         if (!vfioDir.exists()){
  43.             log("!!! Cannot find the VFIO-PCI sysfs at "+vfioDir);
  44.             System.exit(-1);
  45.         }
  46.         if (!(vfioDir.canRead() && vfioDir.canWrite())){
  47.             log("!!! This tool requires R/W access to the VFIO-PCI sysfs at "+vfioDir);
  48.             log("!!! Make sure to run it as root (or similar super user)");
  49.             System.exit(-1);
  50.         }
  51.  
  52.         // Detect list of devices using VFIO-PCI sysfs entry
  53.         log("Detecting VFIO-PCI devices");
  54.         for (File f : vfioDir.listFiles()){            
  55.             if (f.isDirectory() && f.getName().startsWith("00")){
  56.                 Path devicePath = f.toPath().toRealPath();
  57.                 log("\tDevice: "+devicePath);
  58.                
  59.                 try {
  60.                     Path bridgePath = devicePath.getParent();
  61.                     byte[] id = new byte[4];
  62.                     bridgePath.resolve("config").toUri().toURL().openStream().read(id);
  63.                     if (id[0]==0x22 && id[1]==0x10 && id[2]==0x53 && id[3]==0x14){
  64.                         log("\t\tBridge: "+bridgePath);
  65.                         bridgeMapping.put(devicePath, bridgePath);
  66.                     } else {
  67.                         log("\t\t!!! Unknown bridge type! Skipping...");
  68.                     }
  69.                 } catch (IOException ex){
  70.                     log("\t\t!!! Exception: "+ex.getMessage());
  71.                     log("\t\t!!! Skipping...");
  72.                 }
  73.             }
  74.         }
  75.        
  76.         // Monitor devices for bridge failure pattern
  77.         log("Monitoring "+bridgeMapping.size()+" device(s)...");
  78.         while (true){
  79.             for (Entry<Path,Path> bridgeEntry : bridgeMapping.entrySet()){
  80.                 try (FileInputStream deviceConfig = new FileInputStream(bridgeEntry.getKey().resolve("config").toFile())){                    
  81.                     byte[] id = new byte[4];
  82.                     deviceConfig.read(id);
  83.                     if (id[0]==-1 && id[1]==-1){
  84.                         // Failure detected, recover bridge by rewriting its config
  85.                         log("Lost contact with "+bridgeEntry.getKey());
  86.                         byte[] data = new byte[512];
  87.                         try (
  88.                                 FileInputStream bridgeConfigIn = new FileInputStream(bridgeEntry.getValue().resolve("config").toFile());
  89.                                 FileOutputStream bridgeConfigOut = new FileOutputStream(bridgeEntry.getValue().resolve("config").toFile());
  90.                                 ){                                                
  91.                             log("\tRecovering "+bridgeConfigIn.read(data)+" bytes");
  92.                             bridgeConfigOut.write(data);
  93.                             log("\tBridge config write complete");
  94.                         } catch (IOException ex){
  95.                             log("\t!!! Exception: "+ex.getMessage());
  96.                             Thread.sleep(10000);
  97.                         }
  98.                         try (FileInputStream deviceRecoveryConfig = new FileInputStream(bridgeEntry.getKey().resolve("config").toFile())){                    
  99.                             deviceConfig.read(id);
  100.                             if (id[0]==-1 && id[1]==-1){
  101.                                 log("\tFailed to recover bridge secondary bus");
  102.                             } else {
  103.                                 log("\tRecovered bridge secondary bus");
  104.                                 log("Re-acquired contact with "+bridgeEntry.getKey());
  105.                             }
  106.                         }
  107.                     }
  108.                 }
  109.             }
  110.             Thread.sleep(100);
  111.         }
  112.     }
  113.    
  114. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top