Merge dfb889122e
into c1f11ce1c3
This commit is contained in:
commit
b7cf85b8a6
9 changed files with 275 additions and 96 deletions
4
go.mod
4
go.mod
|
@ -6,9 +6,7 @@ require (
|
|||
github.com/HikariKnight/ls-iommu v0.0.0-20230912061539-899ed0ca3fd5
|
||||
github.com/akamensky/argparse v1.4.0
|
||||
github.com/cavaliergopher/grab/v3 v3.0.1
|
||||
github.com/charmbracelet/bubbles v0.17.1
|
||||
github.com/charmbracelet/bubbletea v0.25.0
|
||||
github.com/charmbracelet/lipgloss v0.9.1
|
||||
github.com/gookit/color v1.5.4
|
||||
github.com/klauspost/cpuid/v2 v2.2.6
|
||||
github.com/nexidian/gocliselect v1.0.0
|
||||
|
@ -16,7 +14,6 @@ require (
|
|||
)
|
||||
|
||||
require (
|
||||
github.com/atotto/clipboard v0.1.4 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/buger/goterm v1.0.4 // indirect
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
|
||||
|
@ -30,7 +27,6 @@ require (
|
|||
github.com/muesli/termenv v0.15.2 // indirect
|
||||
github.com/pkg/term v1.1.0 // indirect
|
||||
github.com/rivo/uniseg v0.4.4 // indirect
|
||||
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
golang.org/x/sync v0.5.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
|
|
30
go.sum
30
go.sum
|
@ -2,36 +2,21 @@ github.com/HikariKnight/ls-iommu v0.0.0-20230912061539-899ed0ca3fd5 h1:IEH+I+phC
|
|||
github.com/HikariKnight/ls-iommu v0.0.0-20230912061539-899ed0ca3fd5/go.mod h1:+yX6+uXNeERvwFtP/gH/dOW/MA+K10Wi6asYcRtDXd8=
|
||||
github.com/akamensky/argparse v1.4.0 h1:YGzvsTqCvbEZhL8zZu2AiA5nq805NZh75JNj4ajn1xc=
|
||||
github.com/akamensky/argparse v1.4.0/go.mod h1:S5kwC7IuDcEr5VeXtGPRVZ5o/FdhcMlQz4IZQuw64xA=
|
||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/buger/goterm v1.0.3 h1:7V/HeAQHrzPk/U4BvyH2g9u+xbUW9nr4yRPyG59W4fM=
|
||||
github.com/buger/goterm v1.0.3/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE=
|
||||
github.com/buger/goterm v1.0.4 h1:Z9YvGmOih81P0FbVtEYTFF6YsSgxSUKEhf/f9bTMXbY=
|
||||
github.com/buger/goterm v1.0.4/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE=
|
||||
github.com/cavaliergopher/grab/v3 v3.0.1 h1:4z7TkBfmPjmLAAmkkAZNX/6QJ1nNFdv3SdIHXju0Fr4=
|
||||
github.com/cavaliergopher/grab/v3 v3.0.1/go.mod h1:1U/KNnD+Ft6JJiYoYBAimKH2XrYptb8Kl3DFGmsjpq4=
|
||||
github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY=
|
||||
github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc=
|
||||
github.com/charmbracelet/bubbles v0.17.1 h1:0SIyjOnkrsfDo88YvPgAWvZMwXe26TP6drRvmkjyUu4=
|
||||
github.com/charmbracelet/bubbles v0.17.1/go.mod h1:9HxZWlkCqz2PRwsCbYl7a3KXvGzFaDHpYbSYMJ+nE3o=
|
||||
github.com/charmbracelet/bubbletea v0.24.2 h1:uaQIKx9Ai6Gdh5zpTbGiWpytMU+CfsPp06RaW2cx/SY=
|
||||
github.com/charmbracelet/bubbletea v0.24.2/go.mod h1:XdrNrV4J8GiyshTtx3DNuYkR1FDaJmO3l2nejekbsgg=
|
||||
github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM=
|
||||
github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg=
|
||||
github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg=
|
||||
github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I=
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
|
||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0=
|
||||
github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/48xc=
|
||||
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
|
@ -58,17 +43,10 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ
|
|||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
|
||||
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/sahilm/fuzzy v0.1.0 h1:FzWGaw2Opqyu+794ZQ9SYifWv2EIXpwP4q8dY1kDAwI=
|
||||
github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
||||
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y=
|
||||
github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8=
|
||||
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
||||
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
|
||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
|
||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -76,16 +54,10 @@ golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
|
|
@ -51,7 +51,7 @@ func getBootloader(config *Config) {
|
|||
// This function adds the default kernel arguments we want to the config/cmdline file
|
||||
// This gives us a file we can read all the kernel arguments this system needs
|
||||
// in case of an unknown bootloader
|
||||
func Set_Cmdline(gpu_IDs []string) {
|
||||
func Set_Cmdline(gpu_IDs []string, includeDeviceIdsForVfio bool) {
|
||||
// Get the system info
|
||||
cpuinfo := cpuid.CPU
|
||||
|
||||
|
@ -69,8 +69,10 @@ func Set_Cmdline(gpu_IDs []string) {
|
|||
fileio.AppendContent(" intel_iommu=on", config.Path.CMDLINE)
|
||||
}
|
||||
|
||||
if includeDeviceIdsForVfio {
|
||||
// Add the GPU ids for vfio to the kernel arguments
|
||||
fileio.AppendContent(fmt.Sprintf(" vfio_pci.ids=%s", strings.Join(gpu_IDs, ",")), config.Path.CMDLINE)
|
||||
}
|
||||
}
|
||||
|
||||
// Set_KernelStub configures systemd-boot using kernelstub.
|
||||
|
|
|
@ -3,16 +3,17 @@ package configs
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/HikariKnight/quickpassthrough/internal/common"
|
||||
"github.com/HikariKnight/quickpassthrough/internal/logger"
|
||||
"github.com/HikariKnight/quickpassthrough/pkg/fileio"
|
||||
)
|
||||
|
||||
// Set_Dracut writes a dracut configuration file for `/etc/dracut.conf.d/`.
|
||||
func Set_Dracut() {
|
||||
config := GetConfig()
|
||||
|
||||
func Set_Dracut(config *Config) {
|
||||
// Set the dracut config file
|
||||
dracutConf := fmt.Sprintf("%s/vfio.conf", config.Path.DRACUT)
|
||||
|
||||
|
@ -38,4 +39,61 @@ func Set_Dracut() {
|
|||
|
||||
// Make a backup of dracutConf if there is one there
|
||||
backupFile(strings.Replace(dracutConf, "config", "", 1))
|
||||
|
||||
if config.HasDuplicateDeviceIds {
|
||||
setDracutEarlyBinds(config)
|
||||
}
|
||||
}
|
||||
|
||||
func setDracutEarlyBinds(config *Config) {
|
||||
err := os.MkdirAll(config.Path.DRACUTMODULE, os.ModePerm)
|
||||
common.ErrorCheck(err, "Error, could not create dracut module config directory")
|
||||
confToSystemPathRe := regexp.MustCompile(`^config`)
|
||||
|
||||
earlyBindScriptConfigPath := path.Join(config.Path.DRACUTMODULE, "early-vfio-bind.sh")
|
||||
earlyBindScriptSysPath := confToSystemPathRe.ReplaceAllString(earlyBindScriptConfigPath, "")
|
||||
config.EarlyBindFilePaths[earlyBindScriptConfigPath] = earlyBindScriptSysPath
|
||||
if exists, _ := fileio.FileExist(earlyBindScriptConfigPath); exists {
|
||||
_ = os.Remove(earlyBindScriptConfigPath)
|
||||
}
|
||||
|
||||
logger.Printf("Writing to early bind script to %s", earlyBindScriptConfigPath)
|
||||
vfioBindScript := fmt.Sprintf(`#!/bin/bash
|
||||
DEVS="%s"
|
||||
|
||||
for DEV in $DEVS; do
|
||||
echo "vfio-pci" > /sys/bus/pci/devices/$DEV/driver_override
|
||||
done
|
||||
|
||||
# Load the vfio-pci module
|
||||
modprobe -i vfio-pci`, strings.Join(config.Gpu_Addresses, " "))
|
||||
|
||||
fileio.AppendContent(vfioBindScript, earlyBindScriptConfigPath)
|
||||
err = os.Chmod(earlyBindScriptConfigPath, 0755)
|
||||
common.ErrorCheck(err, fmt.Sprintf("Error, could not chmod %s", earlyBindScriptConfigPath))
|
||||
|
||||
dracutModuleConfigPath := path.Join(config.Path.DRACUTMODULE, "module-setup.sh")
|
||||
dracutModuleSysPath := confToSystemPathRe.ReplaceAllString(dracutModuleConfigPath, "")
|
||||
config.EarlyBindFilePaths[dracutModuleConfigPath] = dracutModuleSysPath
|
||||
if exists, _ := fileio.FileExist(dracutModuleConfigPath); exists {
|
||||
_ = os.Remove(dracutModuleConfigPath)
|
||||
}
|
||||
|
||||
logger.Printf("Writing to dracut early bind config to %s", dracutModuleConfigPath)
|
||||
dracutConfig := fmt.Sprintf(`#!/bin/bash
|
||||
check() {
|
||||
return 0
|
||||
}
|
||||
|
||||
depends() {
|
||||
return 0
|
||||
}
|
||||
|
||||
install() {
|
||||
inst_hook pre-trigger 90 "$moddir/%s"
|
||||
}`, path.Base(earlyBindScriptSysPath))
|
||||
|
||||
fileio.AppendContent(dracutConfig, dracutModuleConfigPath)
|
||||
err = os.Chmod(dracutModuleConfigPath, 0755)
|
||||
common.ErrorCheck(err, fmt.Sprintf("Error, could not chmod %s", dracutModuleConfigPath))
|
||||
}
|
||||
|
|
|
@ -4,10 +4,12 @@ import (
|
|||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/HikariKnight/quickpassthrough/internal/common"
|
||||
"github.com/HikariKnight/quickpassthrough/internal/logger"
|
||||
"github.com/HikariKnight/quickpassthrough/pkg/fileio"
|
||||
)
|
||||
|
||||
|
@ -82,3 +84,31 @@ func initramfs_addModules(conffile string) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SetInitramfsToolsEarlyBinds(config *Config) {
|
||||
confToSystemPathRe := regexp.MustCompile(`^config`)
|
||||
|
||||
earlyBindScriptConfigPath := path.Join(config.Path.INITRAMFS, "/scripts/init-top/early-vfio-bind.sh")
|
||||
earlyBindScriptSysPath := confToSystemPathRe.ReplaceAllString(earlyBindScriptConfigPath, "")
|
||||
config.EarlyBindFilePaths[earlyBindScriptConfigPath] = earlyBindScriptSysPath
|
||||
if exists, _ := fileio.FileExist(earlyBindScriptConfigPath); exists {
|
||||
_ = os.Remove(earlyBindScriptConfigPath)
|
||||
}
|
||||
|
||||
logger.Printf("Writing to early bind script to %s", earlyBindScriptConfigPath)
|
||||
vfioBindScript := fmt.Sprintf(`#!/bin/bash
|
||||
PREREQS=""
|
||||
DEVS="%s"
|
||||
|
||||
for DEV in $DEVS; do
|
||||
echo "vfio-pci" > /sys/bus/pci/devices/$DEV/driver_override
|
||||
done
|
||||
|
||||
# Load the vfio-pci module
|
||||
modprobe -i vfio-pci`, strings.Join(config.Gpu_Addresses, " "))
|
||||
|
||||
fileio.AppendContent(vfioBindScript, earlyBindScriptConfigPath)
|
||||
err := os.Chmod(earlyBindScriptConfigPath, 0755)
|
||||
common.ErrorCheck(err, fmt.Sprintf("Error, could not chmod %s", earlyBindScriptConfigPath))
|
||||
|
||||
}
|
||||
|
|
|
@ -3,18 +3,18 @@ package configs
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/HikariKnight/quickpassthrough/internal/common"
|
||||
"github.com/HikariKnight/quickpassthrough/internal/logger"
|
||||
"github.com/HikariKnight/quickpassthrough/pkg/fileio"
|
||||
)
|
||||
|
||||
// Set_Mkinitcpio copies the content of /etc/mkinitcpio.conf to the config folder and does an inline replace/insert on the MODULES=() line
|
||||
func Set_Mkinitcpio() {
|
||||
// Get the config struct
|
||||
config := GetConfig()
|
||||
|
||||
func Set_Mkinitcpio(config *Config) {
|
||||
// Make sure we start from scratch by deleting any old file
|
||||
if exists, _ := fileio.FileExist(config.Path.MKINITCPIO); exists {
|
||||
_ = os.Remove(config.Path.MKINITCPIO)
|
||||
|
@ -26,6 +26,7 @@ func Set_Mkinitcpio() {
|
|||
|
||||
// Make a regex to find the modules line
|
||||
module_line_re := regexp.MustCompile(`^MODULES=`)
|
||||
hooks_line_re := regexp.MustCompile(`^HOOKS=`)
|
||||
modules_re := regexp.MustCompile(`MODULES=\((.*)\)`)
|
||||
vfio_modules_re := regexp.MustCompile(`(vfio_iommu_type1|vfio_pci|vfio_virqfd|vfio|vendor-reset)`)
|
||||
|
||||
|
@ -67,9 +68,54 @@ func Set_Mkinitcpio() {
|
|||
|
||||
// Write the modules line we generated
|
||||
fileio.AppendContent(fmt.Sprintf("MODULES=(%s)\n", strings.Join(modules, " ")), config.Path.MKINITCPIO)
|
||||
} else if config.HasDuplicateDeviceIds && hooks_line_re.MatchString(line) {
|
||||
setMkinitcpioEarlyBinds(config, line)
|
||||
} else {
|
||||
// Else just write the line to the config
|
||||
fileio.AppendContent(fmt.Sprintf("%s\n", line), config.Path.MKINITCPIO)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func setMkinitcpioEarlyBinds(config *Config, hooksLine string) {
|
||||
err := os.MkdirAll(config.Path.MKINITCPIOHOOKS, os.ModePerm)
|
||||
common.ErrorCheck(err, "Error, could not create mkinitcpio hook config directory")
|
||||
confToSystemPathRe := regexp.MustCompile(`^config`)
|
||||
|
||||
earlyBindHookConfigPath := path.Join(config.Path.MKINITCPIOHOOKS, "early-vfio-bind")
|
||||
earlyBindHookSysPath := confToSystemPathRe.ReplaceAllString(earlyBindHookConfigPath, "")
|
||||
config.EarlyBindFilePaths[earlyBindHookConfigPath] = earlyBindHookSysPath
|
||||
if exists, _ := fileio.FileExist(earlyBindHookConfigPath); exists {
|
||||
_ = os.Remove(earlyBindHookConfigPath)
|
||||
}
|
||||
|
||||
logger.Printf("Writing to early bind hook to %s", earlyBindHookConfigPath)
|
||||
vfioBindHook := fmt.Sprintf(`#!/bin/bash
|
||||
run_hook() {
|
||||
DEVS="%s"
|
||||
|
||||
for DEV in $DEVS; do
|
||||
echo "vfio-pci" > /sys/bus/pci/devices/$DEV/driver_override
|
||||
done
|
||||
|
||||
# Load the vfio-pci module
|
||||
modprobe -i vfio-pci
|
||||
}`, strings.Join(config.Gpu_Addresses, " "))
|
||||
|
||||
fileio.AppendContent(vfioBindHook, earlyBindHookConfigPath)
|
||||
err = os.Chmod(earlyBindHookConfigPath, 0755)
|
||||
common.ErrorCheck(err, fmt.Sprintf("Error, could not chmod %s", earlyBindHookConfigPath))
|
||||
|
||||
hooksString := strings.Trim(strings.Split(hooksLine, "=")[1], "()")
|
||||
hooks := strings.Split(hooksString, " ")
|
||||
customHook := "early-vfio-bind"
|
||||
if !slices.Contains(hooks, customHook) {
|
||||
hooks = append(hooks, customHook)
|
||||
}
|
||||
|
||||
// Write to logger
|
||||
logger.Printf("Replacing line in %s:\n%s\nWith:\nHOOKS=(%s)\n", config.Path.MKINITCPIO, hooksLine, strings.Join(hooks, " "))
|
||||
|
||||
// Write the modules line we generated
|
||||
fileio.AppendContent(fmt.Sprintf("HOOKS=(%s)\n", strings.Join(hooks, " ")), config.Path.MKINITCPIO)
|
||||
}
|
||||
|
|
|
@ -24,7 +24,9 @@ type Path struct {
|
|||
DEFAULT string
|
||||
QEMU string
|
||||
DRACUT string
|
||||
DRACUTMODULE string
|
||||
MKINITCPIO string
|
||||
MKINITCPIOHOOKS string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
|
@ -33,7 +35,10 @@ type Config struct {
|
|||
Path *Path
|
||||
Gpu_Group string
|
||||
Gpu_IDs []string
|
||||
Gpu_Addresses []string
|
||||
EarlyBindFilePaths map[string]string
|
||||
IsRoot bool
|
||||
HasDuplicateDeviceIds bool
|
||||
}
|
||||
|
||||
// GetConfigPaths retrieves the path to all the config files.
|
||||
|
@ -46,7 +51,9 @@ func GetConfigPaths() *Path {
|
|||
DEFAULT: "config/etc/default",
|
||||
QEMU: "config/qemu",
|
||||
DRACUT: "config/etc/dracut.conf.d",
|
||||
DRACUTMODULE: "config/usr/lib/dracut/modules.d/90early-vfio-bind",
|
||||
MKINITCPIO: "config/etc/mkinitcpio.conf",
|
||||
MKINITCPIOHOOKS: "config/etc/initcpio/hooks",
|
||||
}
|
||||
|
||||
return Paths
|
||||
|
@ -60,6 +67,9 @@ func GetConfig() *Config {
|
|||
Path: GetConfigPaths(),
|
||||
Gpu_Group: "",
|
||||
Gpu_IDs: []string{},
|
||||
Gpu_Addresses: []string{},
|
||||
EarlyBindFilePaths: map[string]string{},
|
||||
HasDuplicateDeviceIds: false,
|
||||
}
|
||||
|
||||
// Detect the bootloader we are using
|
||||
|
@ -78,6 +88,7 @@ func InitConfigs() {
|
|||
config.Path.INITRAMFS,
|
||||
config.Path.DEFAULT,
|
||||
config.Path.DRACUT,
|
||||
config.Path.DRACUTMODULE,
|
||||
}
|
||||
|
||||
// Remove old config
|
||||
|
|
|
@ -3,11 +3,13 @@ package pages
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
|
||||
"github.com/gookit/color"
|
||||
|
||||
"github.com/HikariKnight/quickpassthrough/internal/common"
|
||||
"github.com/HikariKnight/quickpassthrough/internal/configs"
|
||||
"github.com/HikariKnight/quickpassthrough/internal/logger"
|
||||
"github.com/HikariKnight/quickpassthrough/internal/lsiommu"
|
||||
"github.com/HikariKnight/quickpassthrough/pkg/command"
|
||||
"github.com/HikariKnight/quickpassthrough/pkg/fileio"
|
||||
|
@ -94,25 +96,23 @@ func viewGPU(config *configs.Config, ext ...int) {
|
|||
// Get the device ids for the selected gpu using ls-iommu
|
||||
config.Gpu_IDs = lsiommu.GetIOMMU("-g", mode, "-i", config.Gpu_Group, "--id")
|
||||
|
||||
// If the kernel_args file already exists
|
||||
if exists, _ := fileio.FileExist(config.Path.CMDLINE); exists {
|
||||
// Delete it as we will have to make a new one anyway
|
||||
err := os.Remove(config.Path.CMDLINE)
|
||||
common.ErrorCheck(err, fmt.Sprintf("Could not remove %s", config.Path.CMDLINE))
|
||||
}
|
||||
|
||||
// Write initial kernel_arg file
|
||||
configs.Set_Cmdline(config.Gpu_IDs)
|
||||
|
||||
// Go to the vbios dumper page
|
||||
genVBIOS_dumper(config)
|
||||
|
||||
case "manual":
|
||||
config.Gpu_IDs = menu.ManualInput(
|
||||
"Please manually enter the vendorID:deviceID for every device to use except PCI Express Switches\n"+
|
||||
"NOTE: All devices sharing the same IOMMU group will still get pulled into the VM!",
|
||||
"xxxx:yyyy,xxxx:yyyy,xxxx:yyyy",
|
||||
)
|
||||
}
|
||||
|
||||
logger.Printf("Checking for duplicate device Ids")
|
||||
config.HasDuplicateDeviceIds = detectDuplicateDeviceIds(config.Gpu_Group, config.Gpu_IDs)
|
||||
|
||||
// TODO remove this
|
||||
config.HasDuplicateDeviceIds = true
|
||||
|
||||
if config.HasDuplicateDeviceIds {
|
||||
config.Gpu_Addresses = lsiommu.GetIOMMU("-g", mode, "-i", config.Gpu_Group, "--pciaddr")
|
||||
}
|
||||
|
||||
// If the kernel_args file already exists
|
||||
if exists, _ := fileio.FileExist(config.Path.CMDLINE); exists {
|
||||
|
@ -122,9 +122,43 @@ func viewGPU(config *configs.Config, ext ...int) {
|
|||
}
|
||||
|
||||
// Write initial kernel_arg file
|
||||
configs.Set_Cmdline(config.Gpu_IDs)
|
||||
configs.Set_Cmdline(config.Gpu_IDs, !config.HasDuplicateDeviceIds)
|
||||
|
||||
// Go to the vbios dumper page
|
||||
genVBIOS_dumper(config)
|
||||
}
|
||||
}
|
||||
|
||||
func detectDuplicateDeviceIds(selectedGpuGroup string, selectedDeviceIds []string) bool {
|
||||
// TODO: this would be made much simpler if ls-iommu allowed using the --id flag without
|
||||
// the "-i" flag.
|
||||
gpus := lsiommu.GetIOMMU("-g", "-F", "vendor:,prod_name,optional_revision:,device_id")
|
||||
iommu_group_regex := regexp.MustCompile(`(\d{1,3})`)
|
||||
iommuGroups := []string{}
|
||||
for _, gpu := range gpus {
|
||||
iommuGroup := iommu_group_regex.FindString(gpu)
|
||||
iommuGroups = append(iommuGroups, iommuGroup)
|
||||
}
|
||||
|
||||
allDeviceIds := []string{}
|
||||
for _, group := range iommuGroups {
|
||||
if group == selectedGpuGroup {
|
||||
continue
|
||||
}
|
||||
|
||||
deviceIds := lsiommu.GetIOMMU("-g", "-r", "-i", group, "--id")
|
||||
for _, deviceId := range deviceIds {
|
||||
allDeviceIds = append(allDeviceIds, deviceId)
|
||||
}
|
||||
}
|
||||
|
||||
for _, deviceId := range allDeviceIds {
|
||||
for _, selectedDeviceId := range selectedDeviceIds {
|
||||
if deviceId == selectedDeviceId {
|
||||
logger.Printf("Found duplicate device id: %s", deviceId)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"os/user"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/gookit/color"
|
||||
|
@ -26,15 +27,20 @@ func prepModules(config *configs.Config) {
|
|||
configs.Set_Modprobe(config.Gpu_IDs)
|
||||
}
|
||||
|
||||
if exists, _ := fileio.FileExist(config.Path.INITRAMFS); exists && config.HasDuplicateDeviceIds {
|
||||
// Configure initramfs early binds
|
||||
configs.SetInitramfsToolsEarlyBinds(config)
|
||||
}
|
||||
|
||||
// If we have a folder for dracut
|
||||
if exists, _ := fileio.FileExist(config.Path.DRACUT); exists {
|
||||
// Configure dracut
|
||||
configs.Set_Dracut()
|
||||
configs.Set_Dracut(config)
|
||||
}
|
||||
|
||||
// If we have a mkinitcpio.conf file
|
||||
if exists, _ := fileio.FileExist(config.Path.MKINITCPIO); exists {
|
||||
configs.Set_Mkinitcpio()
|
||||
configs.Set_Mkinitcpio(config)
|
||||
}
|
||||
|
||||
// Configure grub2 here as we can make the config without sudo
|
||||
|
@ -111,7 +117,7 @@ func installPassthrough(config *configs.Config) {
|
|||
// Get the user data
|
||||
currentUser, err := user.Current()
|
||||
if err != nil {
|
||||
log.Fatalf(err.Error())
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if !config.IsRoot {
|
||||
|
@ -201,6 +207,12 @@ func installPassthrough(config *configs.Config) {
|
|||
// Copy the modules file to /etc/modules
|
||||
configs.CopyToSystem(config.IsRoot, config.Path.ETCMODULES, "/etc/modules")
|
||||
|
||||
if config.HasDuplicateDeviceIds {
|
||||
for configPath, sysPath := range config.EarlyBindFilePaths {
|
||||
configs.CopyToSystem(config.IsRoot, configPath, sysPath)
|
||||
}
|
||||
}
|
||||
|
||||
if err = command.ExecAndLogSudo(config.IsRoot, true, "update-initramfs", "-u"); err != nil {
|
||||
log.Fatalf("Failed to update initramfs: %s", err)
|
||||
}
|
||||
|
@ -209,6 +221,17 @@ func installPassthrough(config *configs.Config) {
|
|||
// Copy dracut config to /etc/dracut.conf.d/vfio
|
||||
configs.CopyToSystem(config.IsRoot, dracutFile, "/etc/dracut.conf.d/vfio")
|
||||
|
||||
if config.HasDuplicateDeviceIds {
|
||||
moduleSysPath := strings.Replace(config.Path.DRACUTMODULE, "config", "", 1)
|
||||
if err := command.ExecAndLogSudo(config.IsRoot, false, "mkdir", "-p", moduleSysPath); err != nil {
|
||||
log.Fatalf("Failed to create dracut module directory: %s", err)
|
||||
}
|
||||
|
||||
for configPath, sysPath := range config.EarlyBindFilePaths {
|
||||
configs.CopyToSystem(config.IsRoot, configPath, sysPath)
|
||||
}
|
||||
}
|
||||
|
||||
// Get systeminfo
|
||||
sysinfo := uname.New()
|
||||
|
||||
|
@ -220,9 +243,16 @@ func installPassthrough(config *configs.Config) {
|
|||
// Copy dracut config to /etc/dracut.conf.d/vfio
|
||||
configs.CopyToSystem(config.IsRoot, config.Path.MKINITCPIO, "/etc/mkinitcpio.conf")
|
||||
|
||||
if config.HasDuplicateDeviceIds {
|
||||
for configPath, sysPath := range config.EarlyBindFilePaths {
|
||||
configs.CopyToSystem(config.IsRoot, configPath, sysPath)
|
||||
}
|
||||
}
|
||||
|
||||
if err = command.ExecAndLogSudo(config.IsRoot, true, "mkinitcpio", "-P"); err != nil {
|
||||
log.Fatalf("Failed to update initramfs: %s", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Make sure prompt end up on next line
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue