massive restructure
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
# ---> Nix
|
||||||
|
# Ignore build outputs from performing a nix-build or `nix build` command
|
||||||
|
result
|
||||||
|
result-*
|
||||||
|
|
||||||
|
# Ignore automatically generated direnv output
|
||||||
|
.direnv
|
||||||
|
|
||||||
Generated
+463
@@ -0,0 +1,463 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"bcdl-free": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785350661,
|
||||||
|
"narHash": "sha256-IEFWX9+OQkvYry8ODdVmRZkD8K0WiPVLRAo/GItzBJs=",
|
||||||
|
"ref": "refs/heads/main",
|
||||||
|
"rev": "8b9fa0ef8047861ca1b8959afdf8079b39a64d53",
|
||||||
|
"revCount": 74,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.pizzasucht.net/KeksNino/free-bandcamp-downloader"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.pizzasucht.net/KeksNino/free-bandcamp-downloader"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"crane": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1766774972,
|
||||||
|
"narHash": "sha256-8qxEFpj4dVmIuPn9j9z6NTbU+hrcGjBOvaxTzre5HmM=",
|
||||||
|
"owner": "ipetkov",
|
||||||
|
"repo": "crane",
|
||||||
|
"rev": "01bc1d404a51a0a07e9d8759cd50a7903e218c82",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "ipetkov",
|
||||||
|
"repo": "crane",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1765835352,
|
||||||
|
"narHash": "sha256-XswHlK/Qtjasvhd1nOa1e8MgZ8GS//jBoTqWtrS1Giw=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "a34fae9c08a15ad73f295041fec82323541400a9",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils_2": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gsr-ui": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785085647,
|
||||||
|
"narHash": "sha256-VerKUIpQHGnXgpmRXzh767X0BJNjpACWdVp391t8n1s=",
|
||||||
|
"owner": "rPlakama",
|
||||||
|
"repo": "gsr-ui-nix",
|
||||||
|
"rev": "1f9a46bcdde0e805ced86a0e995f1449f8f7a12f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "rPlakama",
|
||||||
|
"repo": "gsr-ui-nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"home-manager": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785306346,
|
||||||
|
"narHash": "sha256-DScBkW0fOgpGPK2trNoX3ryLTlaC14+gglFo/BhGJ4g=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"rev": "e705714e918c3b11affcdd15db2cbe3a070420a0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"home-manager_2": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"zen-browser",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1783963347,
|
||||||
|
"narHash": "sha256-r376E2XpakiXwModDHIxlvB6qLq4iFVEq730vxOO4JY=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"rev": "a45a7c451455a51ae740ec3bce4024b312809c29",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"millennium": {
|
||||||
|
"inputs": {
|
||||||
|
"millennium-src": "millennium-src",
|
||||||
|
"nixpkgs": "nixpkgs_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"dir": "packages/nix",
|
||||||
|
"lastModified": 1785163789,
|
||||||
|
"narHash": "sha256-nHTGaYBPKqOY4SPTqRJNX8MfV/GuIjgPCUxDHHeinGc=",
|
||||||
|
"owner": "SteamClientHomebrew",
|
||||||
|
"repo": "Millennium",
|
||||||
|
"rev": "1375ceda332171907e64e9a9324f9a869f715d6c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"dir": "packages/nix",
|
||||||
|
"owner": "SteamClientHomebrew",
|
||||||
|
"repo": "Millennium",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"millennium-src": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1783268941,
|
||||||
|
"narHash": "sha256-MJLJ0I48HXgfOpISTAbDMYMUdWj9A6M+jGQz4uAvwyw=",
|
||||||
|
"owner": "SteamClientHomebrew",
|
||||||
|
"repo": "Millennium",
|
||||||
|
"rev": "f37f05bdbd4727d873a1ad83ce72d062ef9a0c48",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "SteamClientHomebrew",
|
||||||
|
"repo": "Millennium",
|
||||||
|
"rev": "f37f05bdbd4727d873a1ad83ce72d062ef9a0c48",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785350410,
|
||||||
|
"narHash": "sha256-wXYrsdit8Z54aOAUf7/83LDhkY9+RgSuFBO/rFJeHb8=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "00d4d9bc4d406965d1e0081300dd8c854fd4ba11",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-lib": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1765674936,
|
||||||
|
"narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixpkgs.lib",
|
||||||
|
"rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixpkgs.lib",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1781577229,
|
||||||
|
"narHash": "sha256-lrp67w8AulE9Ks53n27I45ADSzbOCn4H+CNW1Ck8B+8=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "567a49d1913ce81ac6e9582e3553dd90a955875f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "567a49d1913ce81ac6e9582e3553dd90a955875f",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785332987,
|
||||||
|
"narHash": "sha256-Eiw4ie++bC7tDWyBEZmcbEeKv1xv0UAihkVTjD4C5VM=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "97478ef76c1f4c40b12fd4a42c1feba41e60650d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_4": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1767026758,
|
||||||
|
"narHash": "sha256-7fsac/f7nh/VaKJ/qm3I338+wAJa/3J57cOGpXi0Sbg=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "346dd96ad74dc4457a9db9de4f4f57dab2e5731d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_5": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1783279667,
|
||||||
|
"narHash": "sha256-/NAkDSsve+GNM0Bt6tleJdCGfsTlK89nPjkVOzZMo0s=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "f205b5574fd0cb7da5b702a2da51507b7f4fdd1b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_6": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1784007870,
|
||||||
|
"narHash": "sha256-djcLt/JJphyNt4eDY9XTly+/WbCK5lqWq9lSgCmJkkQ=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "18b9261cb3294b6d2a06d03f96872827b8fe2698",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"bcdl-free": "bcdl-free",
|
||||||
|
"gsr-ui": "gsr-ui",
|
||||||
|
"home-manager": "home-manager",
|
||||||
|
"millennium": "millennium",
|
||||||
|
"nixpkgs": "nixpkgs_3",
|
||||||
|
"sls-steam": "sls-steam",
|
||||||
|
"xremap-flake": "xremap-flake",
|
||||||
|
"yazi": "yazi",
|
||||||
|
"zen-browser": "zen-browser"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rust-overlay": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"yazi",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1783320166,
|
||||||
|
"narHash": "sha256-l7C/OsjcnWDOk2K3ssj+SBduwL67LashjBqis9+t468=",
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"rev": "20ee15370c9256669d66968b89ee20a4b0a4e673",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "oxalica",
|
||||||
|
"repo": "rust-overlay",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sls-steam": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785275929,
|
||||||
|
"narHash": "sha256-3IbhTuHEqh2tokPGNKnv6x0HcsjOu3hk1MbLYRtzyRQ=",
|
||||||
|
"owner": "AceSLS",
|
||||||
|
"repo": "SLSsteam",
|
||||||
|
"rev": "1906382a482f35b2bc9b124f3849538ab432e4f3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "AceSLS",
|
||||||
|
"repo": "SLSsteam",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"xremap": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1782465938,
|
||||||
|
"narHash": "sha256-BgRp0y5bkmMwRCdIKHrXIbv6Kl7Hn9IphburN7i7sE8=",
|
||||||
|
"owner": "k0kubun",
|
||||||
|
"repo": "xremap",
|
||||||
|
"rev": "6d1d06436ecd54002257029bc26a22ef058d4b63",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "k0kubun",
|
||||||
|
"ref": "v0.15.9",
|
||||||
|
"repo": "xremap",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"xremap-flake": {
|
||||||
|
"inputs": {
|
||||||
|
"crane": "crane",
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"nixpkgs": "nixpkgs_4",
|
||||||
|
"xremap": "xremap"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1782757039,
|
||||||
|
"narHash": "sha256-4CuFwWsQxoNY4Cxz4+GVEmRrMTR5dUOTKN2eNk1KiEI=",
|
||||||
|
"owner": "xremap",
|
||||||
|
"repo": "nix-flake",
|
||||||
|
"rev": "7f161bede2961279dfde194add6aa53d80a9d26d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "xremap",
|
||||||
|
"repo": "nix-flake",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yazi": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils_2",
|
||||||
|
"nixpkgs": "nixpkgs_5",
|
||||||
|
"rust-overlay": "rust-overlay"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785301727,
|
||||||
|
"narHash": "sha256-Z9g04KWv8aEowWW+QIiADE6ct36oIZmrykTzEh5sQ4M=",
|
||||||
|
"owner": "sxyazi",
|
||||||
|
"repo": "yazi",
|
||||||
|
"rev": "319f90e0eab185a231eef5562215ba322e320286",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "sxyazi",
|
||||||
|
"repo": "yazi",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"zen-browser": {
|
||||||
|
"inputs": {
|
||||||
|
"home-manager": "home-manager_2",
|
||||||
|
"nixpkgs": "nixpkgs_6"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1785224333,
|
||||||
|
"narHash": "sha256-8DNJUVM10ktK02V9ZIV064CH+fuPF272VCAZBn6arig=",
|
||||||
|
"owner": "0xc000022070",
|
||||||
|
"repo": "zen-browser-flake",
|
||||||
|
"rev": "5f1a4be4d280e1ae06d61a75775a234b1714da3f",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "0xc000022070",
|
||||||
|
"repo": "zen-browser-flake",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
{
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs";
|
||||||
|
home-manager = {
|
||||||
|
url = "github:nix-community/home-manager";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
sls-steam = {
|
||||||
|
url = "github:AceSLS/SLSsteam";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
zen-browser.url = "github:0xc000022070/zen-browser-flake";
|
||||||
|
xremap-flake.url = "github:xremap/nix-flake";
|
||||||
|
yazi.url = "github:sxyazi/yazi";
|
||||||
|
millennium.url = "github:SteamClientHomebrew/Millennium?dir=packages/nix";
|
||||||
|
gsr-ui = {
|
||||||
|
url = "github:rPlakama/gsr-ui-nix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
bcdl-free.url = "git+https://git.pizzasucht.net/KeksNino/free-bandcamp-downloader";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs =
|
||||||
|
{
|
||||||
|
nixpkgs,
|
||||||
|
home-manager,
|
||||||
|
zen-browser,
|
||||||
|
xremap-flake,
|
||||||
|
sls-steam,
|
||||||
|
yazi,
|
||||||
|
millennium,
|
||||||
|
gsr-ui,
|
||||||
|
bcdl-free,
|
||||||
|
...
|
||||||
|
}@inputs:
|
||||||
|
let
|
||||||
|
system = "x86_64-linux";
|
||||||
|
in
|
||||||
|
{
|
||||||
|
nixosConfigurations.desktop = nixpkgs.lib.nixosSystem {
|
||||||
|
specialArgs = {
|
||||||
|
inherit
|
||||||
|
sls-steam
|
||||||
|
bcdl-free
|
||||||
|
xremap-flake
|
||||||
|
system
|
||||||
|
;
|
||||||
|
};
|
||||||
|
modules = [
|
||||||
|
./hosts/desktop/configuration.nix
|
||||||
|
./hosts/desktop/hardware-configuration.nix
|
||||||
|
./modules/common.nix
|
||||||
|
home-manager.nixosModules.home-manager
|
||||||
|
gsr-ui.nixosModules.default
|
||||||
|
{
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
yazi.overlays.default
|
||||||
|
millennium.overlays.default
|
||||||
|
];
|
||||||
|
|
||||||
|
home-manager.users.user = import ./hosts/desktop/home-manager/home.nix;
|
||||||
|
|
||||||
|
home-manager.extraSpecialArgs = {
|
||||||
|
inherit zen-browser;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.gpu-screen-recorder = {
|
||||||
|
package = gsr-ui.packages.${system}.gpu-screen-recorder;
|
||||||
|
enable = true;
|
||||||
|
ui.enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
nixosConfigurations.music-server = nixpkgs.lib.nixosSystem {
|
||||||
|
specialArgs = { inherit inputs bcdl-free system; };
|
||||||
|
modules = [
|
||||||
|
./hosts/music-server/configuration.nix
|
||||||
|
./hosts/music-server/hardware-configuration.nix
|
||||||
|
./modules/common.nix
|
||||||
|
home-manager.nixosModules.home-manager
|
||||||
|
{
|
||||||
|
home-manager.users.user = import ./hosts/music-server/home-manager/home.nix;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
sls-steam,
|
||||||
|
options,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cpuid-fault-emulation = pkgs.callPackage ../../pkgs/cpuid-fault-emulation {
|
||||||
|
kernel = config.boot.kernelPackages.kernel;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./hardware-configuration.nix
|
||||||
|
./packages.nix
|
||||||
|
../../modules/scripts.nix
|
||||||
|
../../modules/desktop/xremap.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
# DISKS
|
||||||
|
fileSystems."/media/gamedisk4" = {
|
||||||
|
device = "/dev/disk/by-uuid/D290EB87C8A1E82A";
|
||||||
|
fsType = "ntfs3";
|
||||||
|
options = [
|
||||||
|
"uid=1000"
|
||||||
|
"gid=100"
|
||||||
|
"rw"
|
||||||
|
"user"
|
||||||
|
"exec"
|
||||||
|
"umask=000"
|
||||||
|
"nofail"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/media/gamedisk" = {
|
||||||
|
device = "/dev/disk/by-uuid/5C7C14707C1446E4";
|
||||||
|
fsType = "ntfs3";
|
||||||
|
options = [
|
||||||
|
"uid=1000"
|
||||||
|
"gid=100"
|
||||||
|
"rw"
|
||||||
|
"user"
|
||||||
|
"exec"
|
||||||
|
"umask=000"
|
||||||
|
"nofail"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/media/gamedisk2" = {
|
||||||
|
device = "/dev/disk/by-uuid/945A7421DAD8A3CE";
|
||||||
|
fsType = "ntfs3";
|
||||||
|
options = [
|
||||||
|
"uid=1000"
|
||||||
|
"gid=100"
|
||||||
|
"rw"
|
||||||
|
"user"
|
||||||
|
"exec"
|
||||||
|
"umask=000"
|
||||||
|
"nofail"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
nix.settings.experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.kernelParams = [
|
||||||
|
"iomem=relaxed"
|
||||||
|
"iommu=pt"
|
||||||
|
"amd_iommu=on"
|
||||||
|
"kvm.ignore_msrs=1"
|
||||||
|
"mitigations=off"
|
||||||
|
"amdgpu.ppfeaturemask=0xffffffff"
|
||||||
|
"clearcpuid=umip"
|
||||||
|
];
|
||||||
|
|
||||||
|
xdg = {
|
||||||
|
mime.defaultApplications = {
|
||||||
|
"inode/directory" = [ "nemo.desktop" ];
|
||||||
|
"application/x-gnome-saved-search" = [ "nemo.desktop" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
hardware.graphics.enable = true;
|
||||||
|
hardware.graphics.enable32Bit = true;
|
||||||
|
services.hardware.openrgb.enable = true;
|
||||||
|
|
||||||
|
# Bootloader.
|
||||||
|
boot.loader.grub.enable = true;
|
||||||
|
boot.loader.grub.device = "nodev";
|
||||||
|
boot.loader.grub.efiSupport = true;
|
||||||
|
boot.extraModulePackages = [ cpuid-fault-emulation ];
|
||||||
|
|
||||||
|
environment.systemPackages = [
|
||||||
|
(pkgs.writeShellScriptBin "enable-hypervisor" ''
|
||||||
|
sudo modprobe -r kvm_amd kvm
|
||||||
|
sudo modprobe cpuid_fault_emulation
|
||||||
|
'')
|
||||||
|
(pkgs.writeShellScriptBin "disable-hypervisor" ''
|
||||||
|
sudo modprobe -r cpuid_fault_emulation
|
||||||
|
sudo modprobe kvm_amd kvm
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
|
||||||
|
networking.hostName = "nixos-desktop";
|
||||||
|
networking.firewall.enable = false;
|
||||||
|
networking.networkmanager.enable = true;
|
||||||
|
|
||||||
|
# Set your time zone.
|
||||||
|
time.timeZone = "Europe/Berlin";
|
||||||
|
|
||||||
|
# Select internationalisation properties.
|
||||||
|
i18n.defaultLocale = "en_US.UTF-8";
|
||||||
|
|
||||||
|
i18n.extraLocaleSettings = {
|
||||||
|
LC_ADDRESS = "de_DE.UTF-8";
|
||||||
|
LC_IDENTIFICATION = "de_DE.UTF-8";
|
||||||
|
LC_MEASUREMENT = "de_DE.UTF-8";
|
||||||
|
LC_MONETARY = "de_DE.UTF-8";
|
||||||
|
LC_NAME = "de_DE.UTF-8";
|
||||||
|
LC_NUMERIC = "de_DE.UTF-8";
|
||||||
|
LC_PAPER = "de_DE.UTF-8";
|
||||||
|
LC_TELEPHONE = "de_DE.UTF-8";
|
||||||
|
LC_TIME = "de_DE.UTF-8";
|
||||||
|
};
|
||||||
|
|
||||||
|
console.keyMap = "de";
|
||||||
|
|
||||||
|
programs.fish.enable = true;
|
||||||
|
users.users.user = {
|
||||||
|
isNormalUser = true;
|
||||||
|
description = "user";
|
||||||
|
uid = 1000;
|
||||||
|
extraGroups = [
|
||||||
|
"networkmanager"
|
||||||
|
"wheel"
|
||||||
|
"docker"
|
||||||
|
];
|
||||||
|
shell = pkgs.fish;
|
||||||
|
};
|
||||||
|
|
||||||
|
nixpkgs.config.allowUnfree = true;
|
||||||
|
|
||||||
|
programs.niri.enable = true;
|
||||||
|
programs.hyprland = {
|
||||||
|
enable = true;
|
||||||
|
xwayland.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
# environment.loginShellInit = ''
|
||||||
|
# if [ "$(tty)" = "/dev/tty1" ] && [ -z "$WAYLAND_DISPLAY" ]; then
|
||||||
|
# exec start-hyprland
|
||||||
|
# fi
|
||||||
|
# '';
|
||||||
|
|
||||||
|
# NFS / MPD
|
||||||
|
fileSystems."/media/music" = {
|
||||||
|
device = "192.168.132.149:/media/music";
|
||||||
|
fsType = "nfs4";
|
||||||
|
};
|
||||||
|
boot.supportedFilesystems = [ "nfs4" ];
|
||||||
|
|
||||||
|
qt = {
|
||||||
|
enable = true;
|
||||||
|
platformTheme = "qt5ct";
|
||||||
|
style = "breeze";
|
||||||
|
};
|
||||||
|
|
||||||
|
virtualisation.docker.enable = true;
|
||||||
|
services.gvfs.enable = true;
|
||||||
|
services.goxlr-utility.enable = true;
|
||||||
|
services.lact.enable = true;
|
||||||
|
services.rsync.enable = true;
|
||||||
|
programs.kdeconnect.enable = true;
|
||||||
|
programs.neovim.enable = true;
|
||||||
|
programs.tmux.enable = true;
|
||||||
|
programs.bat.enable = true;
|
||||||
|
programs.nh.enable = true;
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
signing = {
|
||||||
|
key = "51AE8C6E80E6AF3BDFBE2BF804B31D181764898D";
|
||||||
|
signByDefault = true;
|
||||||
|
};
|
||||||
|
user = {
|
||||||
|
name = "KeksNino";
|
||||||
|
email = "KeksNino@proton.me";
|
||||||
|
};
|
||||||
|
init = {
|
||||||
|
defaultBranch = "main";
|
||||||
|
};
|
||||||
|
push = {
|
||||||
|
autoSetupRemote = true;
|
||||||
|
};
|
||||||
|
commit = {
|
||||||
|
gpgsign = true;
|
||||||
|
};
|
||||||
|
tag = {
|
||||||
|
gpgsign = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
programs.gnupg.agent = {
|
||||||
|
enable = true;
|
||||||
|
pinentryPackage = pkgs.pinentry-curses;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.steam = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.millennium-steam.override {
|
||||||
|
extraEnv = {
|
||||||
|
LD_AUDIT = "${sls-steam.packages.${pkgs.stdenv.hostPlatform.system}.sls-steam}/library-inject.so:${
|
||||||
|
sls-steam.packages.${pkgs.stdenv.hostPlatform.system}.sls-steam
|
||||||
|
}/SLSsteam.so";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.nix-ld = {
|
||||||
|
enable = true;
|
||||||
|
libraries =
|
||||||
|
options.programs.nix-ld.libraries.default
|
||||||
|
++ (with pkgs; [
|
||||||
|
dbus # libdbus-1.so.3
|
||||||
|
fontconfig # libfontconfig.so.1
|
||||||
|
freetype # libfreetype.so.6
|
||||||
|
glib # libglib-2.0.so.0
|
||||||
|
libGL # libGL.so.1
|
||||||
|
libxkbcommon # libxkbcommon.so.0
|
||||||
|
libx11 # libX11.so.6
|
||||||
|
wayland
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
services.pipewire = {
|
||||||
|
enable = true;
|
||||||
|
alsa.enable = true;
|
||||||
|
pulse.enable = true;
|
||||||
|
jack.enable = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
security.pam.loginLimits = [
|
||||||
|
{
|
||||||
|
domain = "@users";
|
||||||
|
item = "rtprio";
|
||||||
|
type = "-";
|
||||||
|
value = "95";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
domain = "@users";
|
||||||
|
item = "memlock";
|
||||||
|
type = "-";
|
||||||
|
value = "unlimited";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
security.rtkit.enable = true;
|
||||||
|
|
||||||
|
system.stateVersion = "24.11";
|
||||||
|
system.autoUpgrade.enable = false;
|
||||||
|
system.autoUpgrade.allowReboot = true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [
|
||||||
|
"xhci_pci"
|
||||||
|
"ahci"
|
||||||
|
"usbhid"
|
||||||
|
"usb_storage"
|
||||||
|
"sd_mod"
|
||||||
|
];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-amd" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "/dev/disk/by-uuid/ddabcce9-86a5-4dd8-84f1-3afa99a83752";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-uuid/16F5-2D1A";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [
|
||||||
|
"fmask=0077"
|
||||||
|
"dmask=0077"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/media/gamedisk4" = {
|
||||||
|
device = "/dev/disk/by-uuid/D290EB87C8A1E82A";
|
||||||
|
fsType = "ntfs3";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/media/music" = {
|
||||||
|
device = "192.168.132.149:/media/music";
|
||||||
|
fsType = "nfs4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/media/arch" = {
|
||||||
|
device = "/dev/disk/by-uuid/8873d98f-c461-4d34-8867-f4ebd5c205d2";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/media/gamedisk" = {
|
||||||
|
device = "/dev/disk/by-uuid/5C7C14707C1446E4";
|
||||||
|
fsType = "ntfs3";
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [
|
||||||
|
{ device = "/dev/disk/by-uuid/5949c73f-30eb-4956-9e93-70301c88fad8"; }
|
||||||
|
];
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
zen-browser,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./mpd.nix
|
||||||
|
zen-browser.homeModules.beta
|
||||||
|
];
|
||||||
|
|
||||||
|
home.username = "user";
|
||||||
|
home.homeDirectory = "/home/user";
|
||||||
|
|
||||||
|
xdg.userDirs = {
|
||||||
|
enable = true;
|
||||||
|
createDirectories = false;
|
||||||
|
extraConfig = {
|
||||||
|
SCREENSHOTS = "${config.home.homeDirectory}/Pictures/Screenshots";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
xdg.mimeApps = {
|
||||||
|
enable = true;
|
||||||
|
defaultApplications = {
|
||||||
|
"inode/directory" = [ "nemo.desktop" ];
|
||||||
|
"image/*" = [ "imv-dir.desktop" ];
|
||||||
|
"image/gif" = [ "imv-dir.desktop" ];
|
||||||
|
"image/jpeg" = [ "imv-dir.desktop" ];
|
||||||
|
"image/png" = [ "imv-dir.desktop" ];
|
||||||
|
"image/webp" = [ "imv-dir.desktop" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
dconf = {
|
||||||
|
settings = {
|
||||||
|
"org/cinnamon/desktop/applications/terminal" = {
|
||||||
|
exec = "kitty";
|
||||||
|
# exec-arg = ""; # argument
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home.pointerCursor = {
|
||||||
|
enable = true;
|
||||||
|
gtk.enable = true;
|
||||||
|
package = pkgs.adwaita-icon-theme;
|
||||||
|
name = "Adwaita";
|
||||||
|
size = 20;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.zen-browser = {
|
||||||
|
enable = true;
|
||||||
|
setAsDefaultBrowser = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.yazi.enable = true;
|
||||||
|
programs.yazi.enableFishIntegration = true;
|
||||||
|
|
||||||
|
programs.fzf.enable = true;
|
||||||
|
programs.fzf.enableFishIntegration = true;
|
||||||
|
|
||||||
|
programs.eza = {
|
||||||
|
enable = true;
|
||||||
|
enableFishIntegration = true;
|
||||||
|
git = true;
|
||||||
|
icons = "always";
|
||||||
|
extraOptions = [
|
||||||
|
"-1"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.pywal = {
|
||||||
|
enable = true;
|
||||||
|
package = pkgs.pywal16;
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.lazygit.enable = true;
|
||||||
|
programs.lazygit.enableFishIntegration = true;
|
||||||
|
|
||||||
|
programs.rbw = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
pinentry = pkgs.pinentry-curses;
|
||||||
|
email = "KeksNino@proton.me";
|
||||||
|
base_url = "https://vw.pizzasucht.net";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.distrobox.enable = true;
|
||||||
|
services.podman.enable = true;
|
||||||
|
|
||||||
|
programs.rofi.enable = true;
|
||||||
|
programs.rofi.plugins = [ pkgs.rofi-calc ];
|
||||||
|
|
||||||
|
services.polkit-gnome.enable = true;
|
||||||
|
services.cliphist.enable = true;
|
||||||
|
programs.btop.enable = true;
|
||||||
|
services.udiskie.enable = true;
|
||||||
|
programs.cava.enable = true;
|
||||||
|
programs.equibop.enable = true;
|
||||||
|
services.awww.enable = true;
|
||||||
|
services.mpdris2.enable = true;
|
||||||
|
programs.fastfetch.enable = true;
|
||||||
|
programs.prismlauncher.enable = true;
|
||||||
|
programs.fd.enable = true;
|
||||||
|
programs.uv.enable = true;
|
||||||
|
programs.satty.enable = true;
|
||||||
|
programs.mpvpaper.enable = true;
|
||||||
|
programs.obsidian.enable = true;
|
||||||
|
programs.gcc.enable = true;
|
||||||
|
programs.mpv.enable = true;
|
||||||
|
programs.imv.enable = true;
|
||||||
|
programs.aria2.enable = true;
|
||||||
|
programs.qutebrowser = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
colors.webpage.preferred_color_scheme = "dark";
|
||||||
|
auto_save.session = true;
|
||||||
|
scrolling.smooth = true;
|
||||||
|
content.autoplay = false;
|
||||||
|
content.blocking.method = "both";
|
||||||
|
url.default_page = "https://priv.au";
|
||||||
|
};
|
||||||
|
extraConfig = ''
|
||||||
|
c.qt.args = ["disable-features=AcceleratedVideoDecodeLinuxGL"]
|
||||||
|
'';
|
||||||
|
keyBindings = {
|
||||||
|
normal = {
|
||||||
|
"M" = "hint links spawn mpv {hint-url}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
searchEngines = {
|
||||||
|
DEFAULT = "https://priv.au/search?q={}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home.sessionPath = [
|
||||||
|
"${config.home.homeDirectory}/.local/bin"
|
||||||
|
];
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
EDITOR = "nvim";
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.fish = {
|
||||||
|
enable = true;
|
||||||
|
interactiveShellInit = ''
|
||||||
|
nitch
|
||||||
|
set -g fish_key_bindings fish_hybrid_key_bindings
|
||||||
|
set fish_greeting
|
||||||
|
'';
|
||||||
|
shellAliases = {
|
||||||
|
ls = "eza -al --no-time --no-user --no-permissions --no-filesize";
|
||||||
|
ll = "eza -la";
|
||||||
|
cat = "bat";
|
||||||
|
cd = "z";
|
||||||
|
cp = "cp -v";
|
||||||
|
ff = "fastfetch";
|
||||||
|
grep = "grep -i";
|
||||||
|
hyprland = "start-hyprland";
|
||||||
|
mv = "mv -v";
|
||||||
|
n = "nvim";
|
||||||
|
py = "uv run";
|
||||||
|
r = "rsync -avh --info=progress2";
|
||||||
|
rm = "gomi";
|
||||||
|
ssh = "kitty +kitten ssh";
|
||||||
|
nd = "nix develop";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.zoxide.enable = true;
|
||||||
|
programs.zoxide.enableFishIntegration = true;
|
||||||
|
|
||||||
|
home.file.".local/share/Steam/steam.cfg".text = ''
|
||||||
|
BootStrapperInhibitAll=enable
|
||||||
|
BootStrapperForceSelfUpdate=disable
|
||||||
|
'';
|
||||||
|
|
||||||
|
gtk = {
|
||||||
|
enable = true;
|
||||||
|
# theme = {
|
||||||
|
# name = "Materia-dark-compact";
|
||||||
|
# package = pkgs.materia-theme-transparent;
|
||||||
|
# };
|
||||||
|
colorScheme = "dark";
|
||||||
|
};
|
||||||
|
|
||||||
|
home.stateVersion = "26.05";
|
||||||
|
}
|
||||||
@@ -0,0 +1,225 @@
|
|||||||
|
{
|
||||||
|
services.mpd = {
|
||||||
|
enable = true;
|
||||||
|
musicDirectory = "/home/user/Music";
|
||||||
|
playlistDirectory = "/home/user/Music/Playlists";
|
||||||
|
dbFile = "/home/user/.config/mpd/database";
|
||||||
|
# log_file = "~/.config/mpd/log";
|
||||||
|
extraConfig = ''
|
||||||
|
save_absolute_paths_in_playlists "yes"
|
||||||
|
metadata_to_use "+comment"
|
||||||
|
audio_output {
|
||||||
|
type "pipewire"
|
||||||
|
name "Pipewire Sound Server"
|
||||||
|
}
|
||||||
|
audio_output {
|
||||||
|
type "fifo"
|
||||||
|
name "my_fifo"
|
||||||
|
path "/tmp/mpd.fifo"
|
||||||
|
format "44100:16:2"
|
||||||
|
}
|
||||||
|
auto_update "yes"
|
||||||
|
'';
|
||||||
|
network.listenAddress = "/home/user/.config/mpd/socket";
|
||||||
|
};
|
||||||
|
|
||||||
|
services.mpdscribble = {
|
||||||
|
enable = true;
|
||||||
|
endpoints = {
|
||||||
|
"last.fm" = {
|
||||||
|
passwordFile = "/home/user/lastfm_password";
|
||||||
|
username = "KeksNino";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.rmpc.enable = true;
|
||||||
|
programs.rmpc.config = ''
|
||||||
|
#![enable(implicit_some)]
|
||||||
|
#![enable(unwrap_newtypes)]
|
||||||
|
#![enable(unwrap_variant_newtypes)]
|
||||||
|
(
|
||||||
|
address: "/home/user/.config/mpd/socket",
|
||||||
|
password: None,
|
||||||
|
theme: Some("default"),
|
||||||
|
cache_dir: Some("/home/user/Music/rmpc"),
|
||||||
|
on_song_change: None,
|
||||||
|
volume_step: 5,
|
||||||
|
max_fps: 60,
|
||||||
|
scrolloff: 0,
|
||||||
|
wrap_navigation: false,
|
||||||
|
enable_mouse: true,
|
||||||
|
enable_config_hot_reload: true,
|
||||||
|
status_update_interval_ms: 1000,
|
||||||
|
rewind_to_start_sec: None,
|
||||||
|
reflect_changes_to_playlist: false,
|
||||||
|
select_current_song_on_change: false,
|
||||||
|
browser_song_sort: [Track, Disc, Artist, Title],
|
||||||
|
directories_sort: SortFormat(group_by_type: true, reverse: false),
|
||||||
|
album_art: (
|
||||||
|
method: Kitty,
|
||||||
|
max_size_px: (width: 1200, height: 1200),
|
||||||
|
disabled_protocols: ["http://", "https://"],
|
||||||
|
vertical_align: Center,
|
||||||
|
horizontal_align: Center,
|
||||||
|
),
|
||||||
|
keybinds: (
|
||||||
|
global: {
|
||||||
|
":": CommandMode,
|
||||||
|
",": VolumeDown,
|
||||||
|
"s": Stop,
|
||||||
|
".": VolumeUp,
|
||||||
|
"<Tab>": NextTab,
|
||||||
|
"<S-Tab>": PreviousTab,
|
||||||
|
"1": SwitchToTab("Queue"),
|
||||||
|
"2": SwitchToTab("Files"),
|
||||||
|
"3": SwitchToTab("Playlists"),
|
||||||
|
"4": SwitchToTab("Artists"),
|
||||||
|
"5": SwitchToTab("Albums"),
|
||||||
|
"6": SwitchToTab("Search"),
|
||||||
|
//"7": SwitchToTab("Album Artists"),
|
||||||
|
"q": Quit,
|
||||||
|
">": NextTrack,
|
||||||
|
"p": TogglePause,
|
||||||
|
"<": PreviousTrack,
|
||||||
|
"f": SeekForward,
|
||||||
|
"z": ToggleRepeat,
|
||||||
|
"x": ToggleRandom,
|
||||||
|
"c": ToggleConsume,
|
||||||
|
"v": ToggleSingle,
|
||||||
|
"b": SeekBack,
|
||||||
|
"~": ShowHelp,
|
||||||
|
"u": Update,
|
||||||
|
"U": Rescan,
|
||||||
|
"I": ShowCurrentSongInfo,
|
||||||
|
"O": ShowOutputs,
|
||||||
|
"P": ShowDecoders,
|
||||||
|
"R": AddRandom,
|
||||||
|
"<C-p>": ExternalCommand(command: ["/home/user/.scripts/check-playlist.sh"], description: "Check if selected song is already in a playlist"),
|
||||||
|
},
|
||||||
|
navigation: {
|
||||||
|
"k": Up,
|
||||||
|
"j": Down,
|
||||||
|
"h": Left,
|
||||||
|
"l": Right,
|
||||||
|
"<Up>": Up,
|
||||||
|
"<Down>": Down,
|
||||||
|
"<Left>": Left,
|
||||||
|
"<Right>": Right,
|
||||||
|
"<C-k>": PaneUp,
|
||||||
|
"<C-j>": PaneDown,
|
||||||
|
"<C-h>": PaneLeft,
|
||||||
|
"<C-l>": PaneRight,
|
||||||
|
"<C-u>": UpHalf,
|
||||||
|
"N": PreviousResult,
|
||||||
|
"a": Add,
|
||||||
|
"A": AddAll,
|
||||||
|
"r": Rename,
|
||||||
|
"n": NextResult,
|
||||||
|
"g": Top,
|
||||||
|
"<Space>": Select,
|
||||||
|
"<C-Space>": InvertSelection,
|
||||||
|
"G": Bottom,
|
||||||
|
"<CR>": Confirm,
|
||||||
|
"i": FocusInput,
|
||||||
|
"J": MoveDown,
|
||||||
|
"<C-d>": DownHalf,
|
||||||
|
"/": EnterSearch,
|
||||||
|
"<C-c>": Close,
|
||||||
|
"<Esc>": Close,
|
||||||
|
"K": MoveUp,
|
||||||
|
"D": Delete,
|
||||||
|
"B": ShowInfo,
|
||||||
|
},
|
||||||
|
queue: {
|
||||||
|
"D": DeleteAll,
|
||||||
|
"<CR>": Play,
|
||||||
|
"<C-s>": Save,
|
||||||
|
"a": AddToPlaylist,
|
||||||
|
"d": Delete,
|
||||||
|
"C": JumpToCurrent,
|
||||||
|
"X": Shuffle,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
search: (
|
||||||
|
case_sensitive: false,
|
||||||
|
mode: Contains,
|
||||||
|
tags: [
|
||||||
|
(value: "any", label: "Any Tag"),
|
||||||
|
(value: "artist", label: "Artist"),
|
||||||
|
(value: "album", label: "Album"),
|
||||||
|
(value: "albumartist", label: "Album Artist"),
|
||||||
|
(value: "title", label: "Title"),
|
||||||
|
(value: "filename", label: "Filename"),
|
||||||
|
(value: "genre", label: "Genre"),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
artists: (
|
||||||
|
album_display_mode: SplitByDate,
|
||||||
|
album_sort_by: Date,
|
||||||
|
),
|
||||||
|
cava: (
|
||||||
|
framerate: 60,
|
||||||
|
autosens: true,
|
||||||
|
sensitivity: 110, // default 100
|
||||||
|
lower_cutoff_freq: 50, // not passed to cava if not provided
|
||||||
|
higher_cutoff_freq: 10000, // not passed to cava if not provided
|
||||||
|
input: (
|
||||||
|
method: Fifo,
|
||||||
|
source: "/tmp/mpd.fifo",
|
||||||
|
sample_rate: 44100,
|
||||||
|
channels: 2,
|
||||||
|
sample_bits: 16,
|
||||||
|
),
|
||||||
|
smoothing: (
|
||||||
|
noise_reduction: 77,
|
||||||
|
monstercat: true,
|
||||||
|
waves: false,
|
||||||
|
),
|
||||||
|
eq: []
|
||||||
|
),
|
||||||
|
tabs: [
|
||||||
|
(
|
||||||
|
name: "Queue",
|
||||||
|
pane: Split(
|
||||||
|
direction: Horizontal,
|
||||||
|
panes: [
|
||||||
|
(size: "40%", pane: Pane(AlbumArt)),
|
||||||
|
(size: "60%", pane: Split(
|
||||||
|
direction: Vertical,
|
||||||
|
panes: [
|
||||||
|
(size: "95%", pane: Pane(Queue)),
|
||||||
|
(size: "30%", pane: Pane(Cava)),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
name: "Files",
|
||||||
|
pane: Pane(Directories),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
name: "Playlists",
|
||||||
|
pane: Pane(Playlists),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
name: "Artists",
|
||||||
|
pane: Pane(Artists),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
name: "Albums",
|
||||||
|
pane: Pane(Albums),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
name: "Search",
|
||||||
|
pane: Pane(Search),
|
||||||
|
),
|
||||||
|
//(
|
||||||
|
// name: "Album Artists",
|
||||||
|
// pane: Pane(AlbumArtists),
|
||||||
|
//),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
{ pkgs, ... }: {
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
wget
|
||||||
|
kitty
|
||||||
|
gdu
|
||||||
|
jamesdsp
|
||||||
|
grimblast
|
||||||
|
nitch
|
||||||
|
wl-clipboard
|
||||||
|
unzip
|
||||||
|
_7zz
|
||||||
|
tree-sitter
|
||||||
|
nodejs
|
||||||
|
nixfmt
|
||||||
|
decibels
|
||||||
|
nwg-look
|
||||||
|
mpc
|
||||||
|
python3
|
||||||
|
basedpyright
|
||||||
|
waypaper
|
||||||
|
renoise
|
||||||
|
pwvucontrol
|
||||||
|
lsof
|
||||||
|
picard
|
||||||
|
exiftool
|
||||||
|
tlrc
|
||||||
|
libnotify
|
||||||
|
trash-cli
|
||||||
|
spek
|
||||||
|
ffmpeg
|
||||||
|
# wine
|
||||||
|
ripgrep
|
||||||
|
nemo-with-extensions
|
||||||
|
papirus-icon-theme
|
||||||
|
rust-analyzer
|
||||||
|
scdl
|
||||||
|
motrix-next
|
||||||
|
onefetch
|
||||||
|
smartmontools
|
||||||
|
qpwgraph
|
||||||
|
pipewire.jack
|
||||||
|
sysz
|
||||||
|
gomi
|
||||||
|
noctalia-shell
|
||||||
|
discordchatexporter-desktop
|
||||||
|
act
|
||||||
|
ayugram-desktop
|
||||||
|
playerctl
|
||||||
|
musicpresence
|
||||||
|
nixd
|
||||||
|
libsForQt5.qt5ct
|
||||||
|
qt6Packages.qt6ct
|
||||||
|
kdePackages.breeze
|
||||||
|
kdePackages.breeze.qt5
|
||||||
|
gnumake
|
||||||
|
samrewritten
|
||||||
|
gale
|
||||||
|
losslesscut
|
||||||
|
tree
|
||||||
|
stow
|
||||||
|
];
|
||||||
|
|
||||||
|
fonts.packages = with pkgs; [
|
||||||
|
nerd-fonts.caskaydia-mono
|
||||||
|
nerd-fonts.symbols-only
|
||||||
|
nerd-fonts.jetbrains-mono
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./hardware-configuration.nix
|
||||||
|
./packages.nix
|
||||||
|
../../modules/server
|
||||||
|
];
|
||||||
|
|
||||||
|
nix.settings.experimental-features = [
|
||||||
|
"nix-command"
|
||||||
|
"flakes"
|
||||||
|
];
|
||||||
|
|
||||||
|
fileSystems."/media/music" = {
|
||||||
|
device = "/dev/disk/by-uuid/8e6ae06e-a4b5-4ac8-ad15-cb288b14715f";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/home/user/backup" = {
|
||||||
|
device = "/dev/disk/by-uuid/db7d96f1-5c72-42dc-abc1-00de9b73f017";
|
||||||
|
fsType = "ext4";
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.hostId = "6054e036";
|
||||||
|
networking.hostName = "nixos-music";
|
||||||
|
networking.networkmanager.enable = true;
|
||||||
|
networking.firewall.enable = false;
|
||||||
|
|
||||||
|
time.timeZone = "Europe/Berlin";
|
||||||
|
|
||||||
|
i18n.defaultLocale = "en_US.UTF-8";
|
||||||
|
console = {
|
||||||
|
font = "Lat2-Terminus16";
|
||||||
|
keyMap = "de";
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.fish.enable = true;
|
||||||
|
users.users.user = {
|
||||||
|
isNormalUser = true;
|
||||||
|
description = "user";
|
||||||
|
uid = 1000;
|
||||||
|
extraGroups = [
|
||||||
|
"networkmanager"
|
||||||
|
"wheel"
|
||||||
|
"docker"
|
||||||
|
];
|
||||||
|
shell = pkgs.fish;
|
||||||
|
};
|
||||||
|
|
||||||
|
services.tailscale.enable = true;
|
||||||
|
services.rsync.enable = true;
|
||||||
|
programs.nix-ld.enable = true;
|
||||||
|
programs.nh.enable = true;
|
||||||
|
programs.neovim.enable = true;
|
||||||
|
programs.tmux.enable = true;
|
||||||
|
programs.bat.enable = true;
|
||||||
|
programs.git = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
user = {
|
||||||
|
name = "KeksNino";
|
||||||
|
email = "KeksNino@proton.me";
|
||||||
|
};
|
||||||
|
init = {
|
||||||
|
defaultBranch = "main";
|
||||||
|
};
|
||||||
|
push = {
|
||||||
|
autoSetupRemote = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
settings = {
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
PermitRootLogin = "no";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
system.stateVersion = "26.05";
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
modulesPath,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
(modulesPath + "/installer/scan/not-detected.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [
|
||||||
|
"xhci_pci"
|
||||||
|
"ahci"
|
||||||
|
"usb_storage"
|
||||||
|
"uas"
|
||||||
|
"sd_mod"
|
||||||
|
];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "zpool/root";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/var" = {
|
||||||
|
device = "zpool/var";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/nix" = {
|
||||||
|
device = "zpool/nix";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/home" = {
|
||||||
|
device = "zpool/home";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-uuid/FCFD-4472";
|
||||||
|
fsType = "vfat";
|
||||||
|
options = [
|
||||||
|
"fmask=0022"
|
||||||
|
"dmask=0022"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
programs.beets.enable = true;
|
||||||
|
|
||||||
|
# programs.beets.package = pkgs.beets.override {
|
||||||
|
# pluginOverrides = {
|
||||||
|
# filetote = {
|
||||||
|
# enable = true;
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
# };
|
||||||
|
|
||||||
|
programs.beets.settings = {
|
||||||
|
directory = "/home/user/Music/Tracks";
|
||||||
|
|
||||||
|
plugins = [
|
||||||
|
"fetchart"
|
||||||
|
"badfiles"
|
||||||
|
"edit"
|
||||||
|
"fish"
|
||||||
|
"hook"
|
||||||
|
];
|
||||||
|
|
||||||
|
import = {
|
||||||
|
copy = false;
|
||||||
|
move = true;
|
||||||
|
autotag = false;
|
||||||
|
write = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
paths = {
|
||||||
|
default = "$albumartist/$album/$track. $artist - $title";
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchart = {
|
||||||
|
auto = true;
|
||||||
|
sources = [ "filesystem" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
badfiles = {
|
||||||
|
check_on_import = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
hook = {
|
||||||
|
hooks = [
|
||||||
|
{
|
||||||
|
event = "item_imported";
|
||||||
|
command = "echo test";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
{ pkgs, config, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./beets.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
home.username = "user";
|
||||||
|
home.homeDirectory = "/home/user";
|
||||||
|
|
||||||
|
programs.yazi.enable = true;
|
||||||
|
programs.yazi.enableFishIntegration = true;
|
||||||
|
|
||||||
|
programs.fzf.enable = true;
|
||||||
|
programs.fzf.enableFishIntegration = true;
|
||||||
|
|
||||||
|
programs.zoxide.enable = true;
|
||||||
|
programs.zoxide.enableFishIntegration = true;
|
||||||
|
|
||||||
|
programs.gcc.enable = true;
|
||||||
|
|
||||||
|
programs.eza = {
|
||||||
|
enable = true;
|
||||||
|
enableFishIntegration = true;
|
||||||
|
git = true;
|
||||||
|
icons = "always";
|
||||||
|
extraOptions = [
|
||||||
|
"-1"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.btop.enable = true;
|
||||||
|
programs.fastfetch.enable = true;
|
||||||
|
programs.fd.enable = true;
|
||||||
|
|
||||||
|
home.sessionVariables = {
|
||||||
|
EDITOR = "nvim";
|
||||||
|
};
|
||||||
|
|
||||||
|
programs.fish = {
|
||||||
|
enable = true;
|
||||||
|
interactiveShellInit = ''
|
||||||
|
set -g fish_key_bindings fish_hybrid_key_bindings
|
||||||
|
set fish_greeting
|
||||||
|
'';
|
||||||
|
shellAliases = {
|
||||||
|
ls = "eza -al --no-time --no-user --no-permissions --no-filesize";
|
||||||
|
ll = "eza -la";
|
||||||
|
cat = "bat";
|
||||||
|
cd = "z";
|
||||||
|
cp = "cp -v";
|
||||||
|
ff = "fastfetch";
|
||||||
|
grep = "grep -i";
|
||||||
|
mv = "mv -v";
|
||||||
|
n = "nvim";
|
||||||
|
r = "rsync -avh --info=progress2";
|
||||||
|
rm = "gomi";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
home.stateVersion = "26.05";
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{ pkgs, ... }: {
|
||||||
|
|
||||||
|
environment.systemPackages = (
|
||||||
|
with pkgs;
|
||||||
|
[
|
||||||
|
wget
|
||||||
|
nixfmt
|
||||||
|
tree-sitter
|
||||||
|
lsof
|
||||||
|
exiftool
|
||||||
|
trash-cli
|
||||||
|
ffmpeg
|
||||||
|
unzip
|
||||||
|
scdl
|
||||||
|
aria2
|
||||||
|
nodejs
|
||||||
|
gomi
|
||||||
|
bun
|
||||||
|
croc
|
||||||
|
mp3val
|
||||||
|
flac
|
||||||
|
(python314.withPackages (
|
||||||
|
ps: with ps; [
|
||||||
|
requests
|
||||||
|
python-dotenv
|
||||||
|
]
|
||||||
|
))
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{ system, bcdl-free, ... }:
|
||||||
|
{
|
||||||
|
environment.systemPackages = [ bcdl-free.packages.${system}.default ];
|
||||||
|
|
||||||
|
home-manager.useGlobalPkgs = true;
|
||||||
|
home-manager.useUserPackages = true;
|
||||||
|
|
||||||
|
home-manager.backupFileExtension = "backup";
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
{ xremap-flake, ... }:
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
xremap-flake.nixosModules.default
|
||||||
|
];
|
||||||
|
|
||||||
|
services.xremap.enable = true;
|
||||||
|
services.xremap.withHypr = true;
|
||||||
|
|
||||||
|
services.xremap.config.modmap = [
|
||||||
|
{
|
||||||
|
name = "Global";
|
||||||
|
remap = {
|
||||||
|
"CapsLock" = "Esc";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.xremap.config.keymap = [
|
||||||
|
{
|
||||||
|
name = "curly braces";
|
||||||
|
remap = {
|
||||||
|
"KEY_SEMICOLON" = "RIGHTALT-KEY_7";
|
||||||
|
}; # ä -> }
|
||||||
|
remap = {
|
||||||
|
"KEY_APOSTROPHE" = "RIGHTALT-KEY_0";
|
||||||
|
}; # ö -> {
|
||||||
|
remap = {
|
||||||
|
"RIGHTALT-KEY_A" = "KEY_APOSTROPHE";
|
||||||
|
}; # altgr + a -> ä
|
||||||
|
remap = {
|
||||||
|
"RIGHTALT-KEY_W" = "KEY_SEMICOLON";
|
||||||
|
}; # altgr + w -> ö
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
environment.systemPackages = [
|
||||||
|
(pkgs.writeShellScriptBin "scan" ''
|
||||||
|
find . -type f \( -iname "*.mp3" -o -iname "*.flac" -o -iname "*.m4a" -o -iname "*.ogg" -o -iname "*.wav" -o -iname "*.aiff" \) -print0 |
|
||||||
|
xargs -0 -P"$(nproc)" -I{} bash -c '
|
||||||
|
if ffprobe -v quiet -show_entries format_tags \
|
||||||
|
-of default=nw=1:nk=1 "$1" 2>/dev/null |
|
||||||
|
grep -q -E "Visit https?://[^ ]+"; then
|
||||||
|
echo "Match found in: $1"
|
||||||
|
fi
|
||||||
|
' _ {} | sort
|
||||||
|
'')
|
||||||
|
(pkgs.writeShellScriptBin "2scan" ''
|
||||||
|
find . -type f \( -iname "*.mp3" -o -iname "*.flac" -o -iname "*.m4a" -o -iname "*.ogg" -o -iname "*.wav" -o -iname "*.aiff" \) -print0 |
|
||||||
|
xargs -0 -P"$(nproc)" -I{} sh -c '
|
||||||
|
if ! ffprobe -v quiet -show_entries format_tags \
|
||||||
|
-of default=nw=1:nk=1 "$1" 2>/dev/null |
|
||||||
|
grep -q -E "Visit https?://[^ ]+"; then
|
||||||
|
echo "Match found in: $1"
|
||||||
|
fi
|
||||||
|
' _ {}
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./slskd.nix
|
||||||
|
./navidrome.nix
|
||||||
|
./nfs.nix
|
||||||
|
./services.nix
|
||||||
|
./smb.nix
|
||||||
|
./zfs.nix
|
||||||
|
../scripts.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
services.navidrome = {
|
||||||
|
enable = true;
|
||||||
|
user = "user";
|
||||||
|
settings = {
|
||||||
|
MusicFolder = "/home/user/Music";
|
||||||
|
PlaylistsPath = "Playlists";
|
||||||
|
Address = "0.0.0.0";
|
||||||
|
ScanSchedule = "@every 24h";
|
||||||
|
EnableInsightsCollector = false;
|
||||||
|
Scanner.PurgeMissing = "always";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.navidrome.serviceConfig = {
|
||||||
|
ProtectHome = lib.mkForce false;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
services.nfs.server = {
|
||||||
|
enable = true;
|
||||||
|
exports = {
|
||||||
|
"/media/music" = {
|
||||||
|
"192.168.132.0/24" = [
|
||||||
|
"rw"
|
||||||
|
"async"
|
||||||
|
"no_subtree_check"
|
||||||
|
"fsid=1"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
systemd.timers."bc-wishlist-scraper" = {
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "daily";
|
||||||
|
Unit = "bc-wishlist-scraper.service";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."bc-wishlist-scraper" = {
|
||||||
|
script = ''
|
||||||
|
${pkgs.bash}/bin/bash /home/user/bc-wishlist-scraper/run.sh
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.timers."scdl" = {
|
||||||
|
wantedBy = [ "timers.target" ];
|
||||||
|
timerConfig = {
|
||||||
|
OnCalendar = "daily";
|
||||||
|
Unit = "scdl.service";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services."scdl" = {
|
||||||
|
script = ''
|
||||||
|
cd ~/Music/scdl && ${pkgs.scdl}/bin/scdl me -f -c --download-archive archive.txt
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
{ pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
services.slskd = {
|
||||||
|
enable = true;
|
||||||
|
environmentFile = /home/user/slskd_secrets;
|
||||||
|
user = "user";
|
||||||
|
settings = {
|
||||||
|
remote_configuration = true;
|
||||||
|
remote_file_management = true;
|
||||||
|
directories = {
|
||||||
|
downloads = "/media/music/Soulseek";
|
||||||
|
};
|
||||||
|
shares = {
|
||||||
|
directories = [
|
||||||
|
"/media/music/Tracks"
|
||||||
|
"/media/music/Tracks2"
|
||||||
|
"/media/music/samples"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
rooms = [
|
||||||
|
"Rare Music"
|
||||||
|
"nicotine"
|
||||||
|
"! ! LGBTQ+ ! !"
|
||||||
|
"lossless"
|
||||||
|
"Linux"
|
||||||
|
"Breakcore"
|
||||||
|
"Jungle"
|
||||||
|
];
|
||||||
|
transfers = {
|
||||||
|
upload = {
|
||||||
|
speed_limit = 3700;
|
||||||
|
};
|
||||||
|
groups = {
|
||||||
|
blacklisted = {
|
||||||
|
members = [
|
||||||
|
"relay"
|
||||||
|
"smbd"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
user_defined = {
|
||||||
|
my_buddies = {
|
||||||
|
upload = {
|
||||||
|
priority = 1;
|
||||||
|
strategy = "firstinfirstout";
|
||||||
|
slots = 1000;
|
||||||
|
};
|
||||||
|
members = [
|
||||||
|
"noamifur"
|
||||||
|
"mesityl"
|
||||||
|
"diphenhydramine"
|
||||||
|
"monfi"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
soulseek = {
|
||||||
|
description = ''
|
||||||
|
Fuck DRM. Fuck Spotify
|
||||||
|
Discord: keksnino
|
||||||
|
https://www.last.fm/user/KeksNino
|
||||||
|
'';
|
||||||
|
listen_port = 32895;
|
||||||
|
};
|
||||||
|
feature = {
|
||||||
|
swagger = true;
|
||||||
|
};
|
||||||
|
integrations = {
|
||||||
|
webhooks = {
|
||||||
|
discord_relay = {
|
||||||
|
call = {
|
||||||
|
url = "http://localhost:5001/slskd_webhook";
|
||||||
|
};
|
||||||
|
on = [ "UploadFileComplete" ];
|
||||||
|
timeout = 5000;
|
||||||
|
retry = {
|
||||||
|
attempts = 3;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
retention = {
|
||||||
|
files = {
|
||||||
|
incomplete = 20160;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services.slskd-speed = {
|
||||||
|
enable = true;
|
||||||
|
description = "Soulseek True Speed Shower";
|
||||||
|
after = [ "network-online.target" ];
|
||||||
|
wants = [ "network-online.target" ];
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "simple";
|
||||||
|
Environment = "PYTHONUNBUFFERED=1";
|
||||||
|
Restart = "on-failure";
|
||||||
|
RestartSec = 30;
|
||||||
|
StandardOutput = "journal";
|
||||||
|
StandardError = "journal";
|
||||||
|
EnvironmentFile = "/home/user/slskd_secrets";
|
||||||
|
ExecStart = ''
|
||||||
|
${pkgs.python3}/bin/python3 /home/user/slskd-speed.py \
|
||||||
|
-u "$SLSKD_SLSK_USERNAME" \
|
||||||
|
-p "$SLSKD_SLSK_PASSWORD" \
|
||||||
|
-s 30mbit/s \
|
||||||
|
--slskd-url http://localhost:5030 \
|
||||||
|
--slskd-key "$SLSKD_API_KEY" \
|
||||||
|
--loop \
|
||||||
|
--poll-interval 30 \
|
||||||
|
--interval 900
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
services.samba = {
|
||||||
|
enable = true;
|
||||||
|
openFirewall = true;
|
||||||
|
settings = {
|
||||||
|
global = {
|
||||||
|
"workgroup" = "WORKGROUP";
|
||||||
|
"server string" = "smbnix";
|
||||||
|
"security" = "user";
|
||||||
|
"interfaces" = "lo eno1 tailscale0";
|
||||||
|
"hosts allow" = "192.168.132.0/24 100.64.0.0/10 127.0.0.1 localhost";
|
||||||
|
"hosts deny" = "0.0.0.0/0";
|
||||||
|
"guest account" = "nobody";
|
||||||
|
};
|
||||||
|
"Music" = {
|
||||||
|
"path" = "/media/music";
|
||||||
|
"browseable" = "yes";
|
||||||
|
"read only" = "no";
|
||||||
|
"guest ok" = "no";
|
||||||
|
"valid users" = "user";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
boot.loader.grub = {
|
||||||
|
enable = true;
|
||||||
|
zfsSupport = true;
|
||||||
|
efiSupport = true;
|
||||||
|
efiInstallAsRemovable = true;
|
||||||
|
mirroredBoots = [
|
||||||
|
{
|
||||||
|
devices = [ "nodev" ];
|
||||||
|
path = "/boot";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "zpool/root";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
fileSystems."/nix" = {
|
||||||
|
device = "zpool/nix";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
fileSystems."/var" = {
|
||||||
|
device = "zpool/var";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
fileSystems."/home" = {
|
||||||
|
device = "zpool/home";
|
||||||
|
fsType = "zfs";
|
||||||
|
};
|
||||||
|
fileSystems."/boot" = {
|
||||||
|
device = "/dev/disk/by-uuid/FCFD-4472";
|
||||||
|
fsType = "vfat";
|
||||||
|
};
|
||||||
|
boot.zfs.forceImportRoot = false;
|
||||||
|
services.zfs.autoScrub.enable = true;
|
||||||
|
|
||||||
|
swapDevices = [ ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{ stdenv, kernel }:
|
||||||
|
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "cpuid_fault_emulation";
|
||||||
|
version = "0.1";
|
||||||
|
|
||||||
|
src = ./source;
|
||||||
|
|
||||||
|
nativeBuildInputs = kernel.moduleBuildDependencies;
|
||||||
|
hardeningDisable = [
|
||||||
|
"pic"
|
||||||
|
"format"
|
||||||
|
];
|
||||||
|
|
||||||
|
# Patch the hardcoded host paths to point into the Nix store
|
||||||
|
postPatch = ''
|
||||||
|
substituteInPlace Makefile \
|
||||||
|
--replace '/lib/modules/$(KERNEL)/build' '${kernel.dev}/lib/modules/${kernel.modDirVersion}/build' \
|
||||||
|
--replace '$(shell uname -r)' '${kernel.modDirVersion}'
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
install -D cpuid_fault_emulation.ko \
|
||||||
|
$out/lib/modules/${kernel.modDirVersion}/extra/cpuid_fault_emulation.ko
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta.platforms = [ "x86_64-linux" ];
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
obj-m += cpuid_fault_emulation.o
|
||||||
|
cpuid_fault_emulation-y := src/cpuid_fault_emulation.o src/capture_context.o src/run_vm.o
|
||||||
|
|
||||||
|
PWD := $(CURDIR)
|
||||||
|
ccflags-y += -I$(src)/inc
|
||||||
|
asflags-y += -I$(src)/inc
|
||||||
|
|
||||||
|
|
||||||
|
NOCLANG := CONFIG_CLANG_VERSION=0
|
||||||
|
|
||||||
|
KERNEL := $(if $(KERNEL),$(KERNEL),$(shell uname -r))
|
||||||
|
|
||||||
|
ifneq ($(shell grep "CONFIG_CLANG_VERSION" /lib/modules/$(KERNEL)/build/.config), $(NOCLANG))
|
||||||
|
LLVM := LLVM=1
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
all:
|
||||||
|
echo $(MAKE) $(LLVM) -C /lib/modules/$(KERNEL)/build M=$(PWD) modules
|
||||||
|
$(MAKE) $(LLVM) -C /lib/modules/$(KERNEL)/build M=$(PWD) modules
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C /lib/modules/$(KERNEL)/build M=$(PWD) clean
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
PACKAGE_NAME="cpuid_fault_emulation"
|
||||||
|
PACKAGE_VERSION="0.1"
|
||||||
|
|
||||||
|
BUILT_MODULE_NAME="cpuid_fault_emulation"
|
||||||
|
BUILT_MODULE_NAME="cpuid_fault_emulation"
|
||||||
|
DEST_MODULE_LOCATION="/updates"
|
||||||
|
AUTOINSTALL="yes"
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
#ifndef HOST_STATE_H
|
||||||
|
#define HOST_STATE_H
|
||||||
|
|
||||||
|
|
||||||
|
#define GUEST_RAX_OFFSET 0x00
|
||||||
|
#define GUEST_RBX_OFFSET 0x08
|
||||||
|
#define GUEST_RCX_OFFSET 0x10
|
||||||
|
#define GUEST_RDX_OFFSET 0x18
|
||||||
|
#define GUEST_RSI_OFFSET 0x20
|
||||||
|
#define GUEST_RDI_OFFSET 0x28
|
||||||
|
#define GUEST_RSP_OFFSET 0x30
|
||||||
|
#define GUEST_RBP_OFFSET 0x38
|
||||||
|
#define GUEST_R8_OFFSET 0x40
|
||||||
|
#define GUEST_R9_OFFSET 0x48
|
||||||
|
#define GUEST_R10_OFFSET 0x50
|
||||||
|
#define GUEST_R11_OFFSET 0x58
|
||||||
|
#define GUEST_R12_OFFSET 0x60
|
||||||
|
#define GUEST_R13_OFFSET 0x68
|
||||||
|
#define GUEST_R14_OFFSET 0x70
|
||||||
|
#define GUEST_R15_OFFSET 0x78
|
||||||
|
#define GUEST_RIP_OFFSET 0x80
|
||||||
|
#define GUEST_RFLAGS_OFFSET 0x88
|
||||||
|
|
||||||
|
#define HOST_STACK_OFFSET 0x000
|
||||||
|
#define HOST_STACK_SIZE 0x1000
|
||||||
|
#define HOST_VMCB_OFFSET 0x1000
|
||||||
|
#define HOST_HOST_VMCB_OFFSET 0x2000
|
||||||
|
#define HOST_HOST_SAVE_OFFSET 0x3000
|
||||||
|
#define HOST_VMCB_PA_OFFSET 0x4000
|
||||||
|
#define HOST_HOST_VMCB_PA_OFFSET 0x4008
|
||||||
|
#define HOST_REGISTER_OFFSET 0x4010
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
#include "vmcb_layout.h"
|
||||||
|
|
||||||
|
struct GuestRegisters {
|
||||||
|
u64 rax;
|
||||||
|
u64 rbx;
|
||||||
|
u64 rcx;
|
||||||
|
u64 rdx;
|
||||||
|
u64 rsi;
|
||||||
|
u64 rdi;
|
||||||
|
u64 rsp;
|
||||||
|
u64 rbp;
|
||||||
|
u64 r8;
|
||||||
|
u64 r9;
|
||||||
|
u64 r10;
|
||||||
|
u64 r11;
|
||||||
|
u64 r12;
|
||||||
|
u64 r13;
|
||||||
|
u64 r14;
|
||||||
|
u64 r15;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
static_assert(GUEST_RAX_OFFSET == offsetof(struct GuestRegisters, rax));
|
||||||
|
static_assert(GUEST_RBX_OFFSET == offsetof(struct GuestRegisters, rbx));
|
||||||
|
static_assert(GUEST_RCX_OFFSET == offsetof(struct GuestRegisters, rcx));
|
||||||
|
static_assert(GUEST_RDX_OFFSET == offsetof(struct GuestRegisters, rdx));
|
||||||
|
static_assert(GUEST_RSI_OFFSET == offsetof(struct GuestRegisters, rsi));
|
||||||
|
static_assert(GUEST_RDI_OFFSET == offsetof(struct GuestRegisters, rdi));
|
||||||
|
static_assert(GUEST_RSP_OFFSET == offsetof(struct GuestRegisters, rsp));
|
||||||
|
static_assert(GUEST_RBP_OFFSET == offsetof(struct GuestRegisters, rbp));
|
||||||
|
static_assert(GUEST_R8_OFFSET == offsetof(struct GuestRegisters, r8));
|
||||||
|
static_assert(GUEST_R9_OFFSET == offsetof(struct GuestRegisters, r9));
|
||||||
|
static_assert(GUEST_R10_OFFSET == offsetof(struct GuestRegisters, r10));
|
||||||
|
static_assert(GUEST_R11_OFFSET == offsetof(struct GuestRegisters, r11));
|
||||||
|
static_assert(GUEST_R12_OFFSET == offsetof(struct GuestRegisters, r12));
|
||||||
|
static_assert(GUEST_R13_OFFSET == offsetof(struct GuestRegisters, r13));
|
||||||
|
static_assert(GUEST_R14_OFFSET == offsetof(struct GuestRegisters, r14));
|
||||||
|
static_assert(GUEST_R15_OFFSET == offsetof(struct GuestRegisters, r15));
|
||||||
|
|
||||||
|
struct InitialContext {
|
||||||
|
struct GuestRegisters regs;
|
||||||
|
u64 rip;
|
||||||
|
u64 rflags;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(GUEST_RIP_OFFSET == offsetof(struct InitialContext, rip));
|
||||||
|
static_assert(GUEST_RFLAGS_OFFSET == offsetof(struct InitialContext, rflags));
|
||||||
|
|
||||||
|
struct ProcessorStatus {
|
||||||
|
u8 host_stack[HOST_STACK_SIZE];
|
||||||
|
struct VMCB vmcb;
|
||||||
|
struct VMCB host_vmcb;
|
||||||
|
u8 host_save[0x1000];
|
||||||
|
u64 vmcb_pa;
|
||||||
|
u64 host_vmcb_pa;
|
||||||
|
struct GuestRegisters guest_registers;
|
||||||
|
void* page_ptr;
|
||||||
|
u64 prev_hsave_pa;
|
||||||
|
bool cpuid_fault;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(offsetof(struct ProcessorStatus, host_stack) == HOST_STACK_OFFSET);
|
||||||
|
static_assert(offsetof(struct ProcessorStatus, vmcb) == HOST_VMCB_OFFSET);
|
||||||
|
static_assert(offsetof(struct ProcessorStatus, host_vmcb) == HOST_HOST_VMCB_OFFSET);
|
||||||
|
static_assert(offsetof(struct ProcessorStatus, host_save) == HOST_HOST_SAVE_OFFSET);
|
||||||
|
static_assert(offsetof(struct ProcessorStatus, vmcb_pa) == HOST_VMCB_PA_OFFSET);
|
||||||
|
static_assert(offsetof(struct ProcessorStatus, host_vmcb_pa) == HOST_HOST_VMCB_PA_OFFSET);
|
||||||
|
static_assert(offsetof(struct ProcessorStatus, guest_registers) == HOST_REGISTER_OFFSET);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,574 @@
|
|||||||
|
#ifndef VMCB_LAYOUT_H
|
||||||
|
#define VMCB_LAYOUT_H
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
struct InterceptVector0 {
|
||||||
|
u32 read_cr0 : 1;
|
||||||
|
u32 read_cr1 : 1;
|
||||||
|
u32 read_cr2 : 1;
|
||||||
|
u32 read_cr3 : 1;
|
||||||
|
u32 read_cr4 : 1;
|
||||||
|
u32 read_cr5 : 1;
|
||||||
|
u32 read_cr6 : 1;
|
||||||
|
u32 read_cr7 : 1;
|
||||||
|
u32 read_cr8 : 1;
|
||||||
|
u32 read_cr9 : 1;
|
||||||
|
u32 read_cr10 : 1;
|
||||||
|
u32 read_cr11 : 1;
|
||||||
|
u32 read_cr12 : 1;
|
||||||
|
u32 read_cr13 : 1;
|
||||||
|
u32 read_cr14 : 1;
|
||||||
|
u32 read_cr15 : 1;
|
||||||
|
u32 write_cr0 : 1;
|
||||||
|
u32 write_cr1 : 1;
|
||||||
|
u32 write_cr2 : 1;
|
||||||
|
u32 write_cr3 : 1;
|
||||||
|
u32 write_cr4 : 1;
|
||||||
|
u32 write_cr5 : 1;
|
||||||
|
u32 write_cr6 : 1;
|
||||||
|
u32 write_cr7 : 1;
|
||||||
|
u32 write_cr8 : 1;
|
||||||
|
u32 write_cr9 : 1;
|
||||||
|
u32 write_cr10 : 1;
|
||||||
|
u32 write_cr11 : 1;
|
||||||
|
u32 write_cr12 : 1;
|
||||||
|
u32 write_cr13 : 1;
|
||||||
|
u32 write_cr14 : 1;
|
||||||
|
u32 write_cr15 : 1;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct InterceptVector0) == 4);
|
||||||
|
|
||||||
|
struct InterceptVector1 {
|
||||||
|
u32 read_dr0 : 1;
|
||||||
|
u32 read_dr1 : 1;
|
||||||
|
u32 read_dr2 : 1;
|
||||||
|
u32 read_dr3 : 1;
|
||||||
|
u32 read_dr4 : 1;
|
||||||
|
u32 read_dr5 : 1;
|
||||||
|
u32 read_dr6 : 1;
|
||||||
|
u32 read_dr7 : 1;
|
||||||
|
u32 read_dr8 : 1;
|
||||||
|
u32 read_dr9 : 1;
|
||||||
|
u32 read_dr10 : 1;
|
||||||
|
u32 read_dr11 : 1;
|
||||||
|
u32 read_dr12 : 1;
|
||||||
|
u32 read_dr13 : 1;
|
||||||
|
u32 read_dr14 : 1;
|
||||||
|
u32 read_dr15 : 1;
|
||||||
|
u32 write_dr0 : 1;
|
||||||
|
u32 write_dr1 : 1;
|
||||||
|
u32 write_dr2 : 1;
|
||||||
|
u32 write_dr3 : 1;
|
||||||
|
u32 write_dr4 : 1;
|
||||||
|
u32 write_dr5 : 1;
|
||||||
|
u32 write_dr6 : 1;
|
||||||
|
u32 write_dr7 : 1;
|
||||||
|
u32 write_dr8 : 1;
|
||||||
|
u32 write_dr9 : 1;
|
||||||
|
u32 write_dr10 : 1;
|
||||||
|
u32 write_dr11 : 1;
|
||||||
|
u32 write_dr12 : 1;
|
||||||
|
u32 write_dr13 : 1;
|
||||||
|
u32 write_dr14 : 1;
|
||||||
|
u32 write_dr15 : 1;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct InterceptVector1) == 4);
|
||||||
|
|
||||||
|
struct InterceptVector2 {
|
||||||
|
u32 exception_vector0 : 1;
|
||||||
|
u32 exception_vector1 : 1;
|
||||||
|
u32 exception_vector2 : 1;
|
||||||
|
u32 exception_vector3 : 1;
|
||||||
|
u32 exception_vector4 : 1;
|
||||||
|
u32 exception_vector5 : 1;
|
||||||
|
u32 exception_vector6 : 1;
|
||||||
|
u32 exception_vector7 : 1;
|
||||||
|
u32 exception_vector8 : 1;
|
||||||
|
u32 exception_vector9 : 1;
|
||||||
|
u32 exception_vector10 : 1;
|
||||||
|
u32 exception_vector11 : 1;
|
||||||
|
u32 exception_vector12 : 1;
|
||||||
|
u32 exception_vector13 : 1;
|
||||||
|
u32 exception_vector14 : 1;
|
||||||
|
u32 exception_vector15 : 1;
|
||||||
|
u32 exception_vector16 : 1;
|
||||||
|
u32 exception_vector17 : 1;
|
||||||
|
u32 exception_vector18 : 1;
|
||||||
|
u32 exception_vector19 : 1;
|
||||||
|
u32 exception_vector20 : 1;
|
||||||
|
u32 exception_vector21 : 1;
|
||||||
|
u32 exception_vector22 : 1;
|
||||||
|
u32 exception_vector23 : 1;
|
||||||
|
u32 exception_vector24 : 1;
|
||||||
|
u32 exception_vector25 : 1;
|
||||||
|
u32 exception_vector26 : 1;
|
||||||
|
u32 exception_vector27 : 1;
|
||||||
|
u32 exception_vector28 : 1;
|
||||||
|
u32 exception_vector29 : 1;
|
||||||
|
u32 exception_vector30 : 1;
|
||||||
|
u32 exception_vector31 : 1;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct InterceptVector2) == 4);
|
||||||
|
|
||||||
|
struct InterceptVector3 {
|
||||||
|
u32 intr : 1;
|
||||||
|
u32 nmi : 1;
|
||||||
|
u32 smi : 1;
|
||||||
|
u32 init : 1;
|
||||||
|
u32 vintr : 1;
|
||||||
|
u32 cr0_writes : 1;
|
||||||
|
u32 idtr_read : 1;
|
||||||
|
u32 gdtr_read : 1;
|
||||||
|
u32 ldtr_read : 1;
|
||||||
|
u32 tr_read : 1;
|
||||||
|
u32 idtr_write : 1;
|
||||||
|
u32 gdtr_write : 1;
|
||||||
|
u32 ldtr_write : 1;
|
||||||
|
u32 tr_write : 1;
|
||||||
|
u32 rdtsc_inst : 1;
|
||||||
|
u32 rdpmc_inst : 1;
|
||||||
|
u32 pushf_inst : 1;
|
||||||
|
u32 popf_inst : 1;
|
||||||
|
u32 cpuid_inst : 1;
|
||||||
|
u32 rsm_inst : 1;
|
||||||
|
u32 iret_inst : 1;
|
||||||
|
u32 intn_inst : 1;
|
||||||
|
u32 invd_inst : 1;
|
||||||
|
u32 pause_inst : 1;
|
||||||
|
u32 hlt_inst : 1;
|
||||||
|
u32 invlpg_inst : 1;
|
||||||
|
u32 invlpga_inst : 1;
|
||||||
|
u32 ioio_prot : 1;
|
||||||
|
u32 msr_prot : 1;
|
||||||
|
u32 task_switches : 1;
|
||||||
|
u32 ferr_freeze : 1;
|
||||||
|
u32 shutdown : 1;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct InterceptVector3) == 4);
|
||||||
|
|
||||||
|
struct InterceptVector4 {
|
||||||
|
u32 vmrun_inst : 1;
|
||||||
|
u32 vmcall_inst : 1;
|
||||||
|
u32 vmload_inst : 1;
|
||||||
|
u32 vmsave_inst : 1;
|
||||||
|
u32 stgi_inst : 1;
|
||||||
|
u32 clgi_inst : 1;
|
||||||
|
u32 skinit_inst : 1;
|
||||||
|
u32 rdtscp_inst : 1;
|
||||||
|
u32 icebp_inst : 1;
|
||||||
|
u32 wbinvd_inst : 1;
|
||||||
|
u32 monitor_inst : 1;
|
||||||
|
u32 mwait_inst_uncond : 1;
|
||||||
|
u32 mwait_inst_armed : 1;
|
||||||
|
u32 xsetbv_inst : 1;
|
||||||
|
u32 rdpru_inst : 1;
|
||||||
|
u32 efer_write : 1;
|
||||||
|
u32 write_cr0_after : 1;
|
||||||
|
u32 write_cr1_after : 1;
|
||||||
|
u32 write_cr2_after : 1;
|
||||||
|
u32 write_cr3_after : 1;
|
||||||
|
u32 write_cr4_after : 1;
|
||||||
|
u32 write_cr5_after : 1;
|
||||||
|
u32 write_cr6_after : 1;
|
||||||
|
u32 write_cr7_after : 1;
|
||||||
|
u32 write_cr8_after : 1;
|
||||||
|
u32 write_cr9_after : 1;
|
||||||
|
u32 write_cr10_after : 1;
|
||||||
|
u32 write_cr11_after : 1;
|
||||||
|
u32 write_cr12_after : 1;
|
||||||
|
u32 write_cr13_after : 1;
|
||||||
|
u32 write_cr14_after : 1;
|
||||||
|
u32 write_cr15_after : 1;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct InterceptVector4) == 4);
|
||||||
|
|
||||||
|
struct InterceptVector5 {
|
||||||
|
u32 invlpgb_inst_all : 1;
|
||||||
|
u32 invlpgb_inst_ill : 1;
|
||||||
|
u32 invpcid_inst : 1;
|
||||||
|
u32 mcommit_inst : 1;
|
||||||
|
u32 tlbsync_inst : 1;
|
||||||
|
u32 bus_lock_op : 1;
|
||||||
|
u32 hlt_inst_npen : 1;
|
||||||
|
u32 reserved : 25;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct InterceptVector5) == 4);
|
||||||
|
|
||||||
|
struct TLBControl {
|
||||||
|
u32 tlb_control : 8;
|
||||||
|
u32 allow_larger_rap : 1;
|
||||||
|
u32 clear_rap : 1;
|
||||||
|
u32 reserved : 22;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct TLBControl) == 4);
|
||||||
|
|
||||||
|
struct VirtualInterruptControl {
|
||||||
|
u64 v_tpr : 4;
|
||||||
|
u64 v_tpr_mbz : 4;
|
||||||
|
u64 v_irq : 1;
|
||||||
|
u64 v_gif : 1;
|
||||||
|
u64 reserved_0 : 1;
|
||||||
|
u64 v_nmi : 1;
|
||||||
|
u64 v_nmi_mask : 1;
|
||||||
|
u64 reserved_1 : 3;
|
||||||
|
u64 v_intr_prio : 4;
|
||||||
|
u64 v_ign_tpr : 1;
|
||||||
|
u64 reserved_2 : 3;
|
||||||
|
u64 v_intr_masking : 1;
|
||||||
|
u64 v_gif_enable : 1;
|
||||||
|
u64 v_nmi_enable : 1;
|
||||||
|
u64 reserved_3 : 3;
|
||||||
|
u64 x2avic_enable : 1;
|
||||||
|
u64 avic_enable : 1;
|
||||||
|
u64 v_intr_vector : 8;
|
||||||
|
u64 reserved_4 : 24;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct VirtualInterruptControl) == 8);
|
||||||
|
|
||||||
|
struct InterruptShadow {
|
||||||
|
u64 interrupt_shadow : 1;
|
||||||
|
u64 guest_interrupt_mask : 1;
|
||||||
|
u64 reserved : 62;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct InterruptShadow) == 8);
|
||||||
|
|
||||||
|
struct VirtualizationControl0 {
|
||||||
|
u64 np_enable : 1;
|
||||||
|
u64 sev_enable : 1;
|
||||||
|
u64 sev_es : 1;
|
||||||
|
u64 guest_mode_execute_trap : 1;
|
||||||
|
u64 ssscheck_en : 1;
|
||||||
|
u64 virtual_transparent_encryption : 1;
|
||||||
|
u64 read_only_guest_page_tables : 1;
|
||||||
|
u64 invlpg_tlbsync_enable : 1;
|
||||||
|
u64 reserved : 56;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct VirtualizationControl0) == 8);
|
||||||
|
|
||||||
|
struct AVICAPICBar {
|
||||||
|
u64 avic_apic_bar : 52;
|
||||||
|
u64 reserved : 12;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct AVICAPICBar) == 8);
|
||||||
|
|
||||||
|
struct VirtualizationControl1 {
|
||||||
|
u64 lbr_virtualization_enable : 1;
|
||||||
|
u64 vmsave_vmload_virtualization_enable : 1;
|
||||||
|
u64 ibs_virtualization_enable : 1;
|
||||||
|
u64 pmc_virtualization_enable : 1;
|
||||||
|
u64 ignored : 60;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct VirtualizationControl1) == 8);
|
||||||
|
|
||||||
|
struct GuestInstruction {
|
||||||
|
u8 bytes_fetched;
|
||||||
|
u8 guest_instruction[0xF];
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct GuestInstruction) == 0x10);
|
||||||
|
|
||||||
|
struct AVICAPICBackingPage {
|
||||||
|
u64 avic_apic_backing_page_pointer : 52;
|
||||||
|
u64 reserved : 12;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct AVICAPICBackingPage) == 8);
|
||||||
|
|
||||||
|
struct AVICLogicalTablePointer {
|
||||||
|
u64 reserved_0 : 12;
|
||||||
|
u64 avic_logical_table_pointer : 40;
|
||||||
|
u64 reserved_1 : 12;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct AVICLogicalTablePointer) == 8);
|
||||||
|
|
||||||
|
struct AVICPhysicalTablePointer {
|
||||||
|
u64 avic_physical_max_index : 12;
|
||||||
|
u64 avic_physical_table_pointer : 40;
|
||||||
|
u64 reserved_0 : 12;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct AVICPhysicalTablePointer) == 8);
|
||||||
|
|
||||||
|
struct VMSAPointer {
|
||||||
|
u64 reserved_0 : 12;
|
||||||
|
u64 vmsa_pointer : 40;
|
||||||
|
u64 reserved_1 : 12;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct VMSAPointer) == 8);
|
||||||
|
|
||||||
|
struct AllowedSEVFeatures {
|
||||||
|
u64 allowed_sev_features_mask : 62;
|
||||||
|
u64 reserved_0 : 1;
|
||||||
|
u64 allowed_sev_features_en : 1;
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct AllowedSEVFeatures) == 8);
|
||||||
|
|
||||||
|
struct RequestedIRR {
|
||||||
|
u64 irr[4];
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct RequestedIRR) == 0x20);
|
||||||
|
|
||||||
|
struct VMCBControlArea {
|
||||||
|
struct InterceptVector0 intercept_vector0;
|
||||||
|
struct InterceptVector1 intercept_vector1;
|
||||||
|
struct InterceptVector2 intercept_vector2;
|
||||||
|
struct InterceptVector3 intercept_vector3;
|
||||||
|
struct InterceptVector4 intercept_vector4;
|
||||||
|
struct InterceptVector5 intercept_vector5;
|
||||||
|
u8 reserved_0[0x24];
|
||||||
|
u16 pause_filter_threshold;
|
||||||
|
u16 pause_filter_count;
|
||||||
|
u64 iopm_base_pa;
|
||||||
|
u64 msrpm_base_pa;
|
||||||
|
u64 tsc_offset;
|
||||||
|
u32 guest_asid;
|
||||||
|
struct TLBControl tlb_control;
|
||||||
|
struct VirtualInterruptControl v_intr;
|
||||||
|
struct InterruptShadow interrupt_shadow;
|
||||||
|
u64 exitcode;
|
||||||
|
u64 exitinfo1;
|
||||||
|
u64 exitinfo2;
|
||||||
|
u64 exitintinfo;
|
||||||
|
struct VirtualizationControl0 virtualization_control0;
|
||||||
|
struct AVICAPICBar avic_apic_bar;
|
||||||
|
u64 guest_ghcb_pa;
|
||||||
|
u64 eventinj;
|
||||||
|
u64 h_cr3;
|
||||||
|
struct VirtualizationControl1 virtualization_control1;
|
||||||
|
u32 vmcb_clean_bits;
|
||||||
|
u8 reserved_1[0x4];
|
||||||
|
u64 nrip;
|
||||||
|
struct GuestInstruction guest_instruction;
|
||||||
|
struct AVICAPICBackingPage avicapic_backing_page;
|
||||||
|
u8 reserved_2[0x8];
|
||||||
|
struct AVICLogicalTablePointer avic_logical_table;
|
||||||
|
struct AVICPhysicalTablePointer avic_physical_table;
|
||||||
|
u8 reserved_3[0x08];
|
||||||
|
struct VMSAPointer vmsa_pointer;
|
||||||
|
u64 vmgexit_rax;
|
||||||
|
u8 vmgexit_cpl;
|
||||||
|
u8 reserved_4[0x07];
|
||||||
|
u16 bus_lock_threshold_counter;
|
||||||
|
u8 reserved_5[0x12];
|
||||||
|
u32 update_irr;
|
||||||
|
struct AllowedSEVFeatures allowed_sev_features;
|
||||||
|
u64 guest_sev_features;
|
||||||
|
u8 reserved_6[0x8];
|
||||||
|
struct RequestedIRR requested_irr;
|
||||||
|
u8 reserved_7[0x270];
|
||||||
|
u8 host_reserved[0x20];
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, intercept_vector0) == 0x000);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, intercept_vector1) == 0x004);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, intercept_vector2) == 0x008);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, intercept_vector3) == 0x00C);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, intercept_vector4) == 0x010);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, intercept_vector5) == 0x014);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, pause_filter_threshold) == 0x03C);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, pause_filter_count) == 0x03E);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, intercept_vector5) == 0x014);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, iopm_base_pa) == 0x040);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, msrpm_base_pa) == 0x048);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, tsc_offset) == 0x050);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, guest_asid) == 0x058);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, tlb_control) == 0x05C);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, v_intr) == 0x060);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, interrupt_shadow) == 0x068);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, exitcode) == 0x070);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, exitinfo1) == 0x078);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, exitinfo2) == 0x080);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, exitintinfo) == 0x088);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, virtualization_control0) == 0x090);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, avic_apic_bar) == 0x098);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, guest_ghcb_pa) == 0x0A0);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, eventinj) == 0x0A8);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, h_cr3) == 0x0B0);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, virtualization_control1) == 0x0B8);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, vmcb_clean_bits) == 0x0C0);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, nrip) == 0x0C8);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, guest_instruction) == 0x0D0);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, avicapic_backing_page) == 0x0E0);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, avic_logical_table) == 0x0F0);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, avic_physical_table) == 0x0F8);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, vmsa_pointer) == 0x108);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, vmgexit_rax) == 0x110);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, vmgexit_cpl) == 0x118);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, bus_lock_threshold_counter) == 0x120);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, update_irr) == 0x134);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, allowed_sev_features) == 0x138);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, guest_sev_features) == 0x140);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, requested_irr) == 0x150);
|
||||||
|
static_assert(offsetof(struct VMCBControlArea, host_reserved) == 0x3E0);
|
||||||
|
static_assert(sizeof(struct VMCBControlArea) == 0x400);
|
||||||
|
|
||||||
|
struct SegmentDescriptor {
|
||||||
|
u16 selector;
|
||||||
|
u16 attrib;
|
||||||
|
u32 limit;
|
||||||
|
u64 base;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
static_assert(offsetof(struct SegmentDescriptor, selector) == 0);
|
||||||
|
static_assert(offsetof(struct SegmentDescriptor, attrib) == 2);
|
||||||
|
static_assert(offsetof(struct SegmentDescriptor, limit) == 4);
|
||||||
|
static_assert(offsetof(struct SegmentDescriptor, base) == 8);
|
||||||
|
static_assert(sizeof(struct SegmentDescriptor) == 0x10);
|
||||||
|
|
||||||
|
struct LBRSTACK {
|
||||||
|
u8 lbr_stack_from_to[256];
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(sizeof(struct LBRSTACK) == 0x100);
|
||||||
|
|
||||||
|
struct VMCBStateSaveArea {
|
||||||
|
struct SegmentDescriptor es;
|
||||||
|
struct SegmentDescriptor cs;
|
||||||
|
struct SegmentDescriptor ss;
|
||||||
|
struct SegmentDescriptor ds;
|
||||||
|
struct SegmentDescriptor fs;
|
||||||
|
struct SegmentDescriptor gs;
|
||||||
|
struct SegmentDescriptor gdtr;
|
||||||
|
struct SegmentDescriptor ldtr;
|
||||||
|
struct SegmentDescriptor idtr;
|
||||||
|
struct SegmentDescriptor tr;
|
||||||
|
u8 reserved_0[0x2B];
|
||||||
|
u8 cpl;
|
||||||
|
u8 reserved_1[0x4];
|
||||||
|
u64 efer;
|
||||||
|
u8 reserved_2[0x8];
|
||||||
|
u64 perf_ctl0;
|
||||||
|
u64 perf_ctr0;
|
||||||
|
u64 perf_ctl1;
|
||||||
|
u64 perf_ctr1;
|
||||||
|
u64 perf_ctl2;
|
||||||
|
u64 perf_ctr2;
|
||||||
|
u64 perf_ctl3;
|
||||||
|
u64 perf_ctr3;
|
||||||
|
u64 perf_ctl4;
|
||||||
|
u64 perf_ctr4;
|
||||||
|
u64 perf_ctl5;
|
||||||
|
u64 perf_ctr5;
|
||||||
|
u8 reserved_3[0x8];
|
||||||
|
u64 cr4;
|
||||||
|
u64 cr3;
|
||||||
|
u64 cr0;
|
||||||
|
u64 dr7;
|
||||||
|
u64 dr6;
|
||||||
|
u64 rflags;
|
||||||
|
u64 rip;
|
||||||
|
u8 reserved_4[0x40];
|
||||||
|
u64 instr_retired_ctr;
|
||||||
|
u64 perf_ctr_global_sts;
|
||||||
|
u64 perf_ctr_global_ctl;
|
||||||
|
u64 rsp;
|
||||||
|
u64 s_cet;
|
||||||
|
u64 ssp;
|
||||||
|
u64 isst_addr;
|
||||||
|
u64 rax;
|
||||||
|
u64 star;
|
||||||
|
u64 lstar;
|
||||||
|
u64 cstar;
|
||||||
|
u64 sfmask;
|
||||||
|
u64 kernel_gs_base;
|
||||||
|
u64 sysenter_cs;
|
||||||
|
u64 sysenter_esp;
|
||||||
|
u64 sysenter_eip;
|
||||||
|
u64 cr2;
|
||||||
|
u8 reserved_5[0x20];
|
||||||
|
u64 g_pat;
|
||||||
|
u64 dbgctl;
|
||||||
|
u64 br_from;
|
||||||
|
u64 br_to;
|
||||||
|
u64 lastexcpfrom;
|
||||||
|
u64 lastexcpto;
|
||||||
|
u64 dbgextnctl;
|
||||||
|
u8 reserved_6[0x40];
|
||||||
|
u64 spec_ctrl;
|
||||||
|
u8 reserved_7[0x388];
|
||||||
|
struct LBRSTACK lbr_stack_from_to;
|
||||||
|
u64 lbr_select;
|
||||||
|
u64 ibs_fetch_ctl;
|
||||||
|
u64 ibs_fetch_linaddr;
|
||||||
|
u64 ibs_op_ctl;
|
||||||
|
u64 ibs_op_rip;
|
||||||
|
u64 ibs_op_data;
|
||||||
|
u64 ibs_op_data2;
|
||||||
|
u64 ibs_op_data3;
|
||||||
|
u64 ibs_dc_linaddr;
|
||||||
|
u64 bp_ibstgt_rip;
|
||||||
|
u64 ic_ibs_extd_ctl;
|
||||||
|
u8 reserved_9[0x38];
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, es) == 0x000);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, cs) == 0x010);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, ss) == 0x020);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, ds) == 0x030);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, fs) == 0x040);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, gs) == 0x050);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, gdtr) == 0x060);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, ldtr) == 0x070);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, idtr) == 0x080);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, tr) == 0x090);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, cpl) == 0x0CB);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, efer) == 0x0D0);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctl0) == 0x0E0);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr0) == 0x0E8);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctl1) == 0x0F0);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr1) == 0x0F8);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctl2) == 0x100);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr2) == 0x108);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctl3) == 0x110);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr3) == 0x118);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctl4) == 0x120);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr4) == 0x128);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctl5) == 0x130);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr5) == 0x138);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, cr4) == 0x148);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, cr3) == 0x150);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, cr0) == 0x158);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, dr7) == 0x160);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, dr6) == 0x168);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, rflags) == 0x170);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, rip) == 0x178);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, instr_retired_ctr) == 0x1C0);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr_global_sts) == 0x1C8);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, perf_ctr_global_ctl) == 0x1D0);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, rsp) == 0x1D8);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, rax) == 0x1F8);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, star) == 0x200);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, lstar) == 0x208);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, cstar) == 0x210);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, sfmask) == 0x218);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, kernel_gs_base) == 0x220);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, sysenter_cs) == 0x228);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, sysenter_esp) == 0x230);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, sysenter_eip) == 0x238);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, cr2) == 0x240);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, g_pat) == 0x268);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, dbgctl) == 0x270);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, br_from) == 0x278);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, br_to) == 0x280);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, lastexcpfrom) == 0x288);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, lastexcpto) == 0x290);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, dbgextnctl) == 0x298);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, spec_ctrl) == 0x2E0);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, lbr_stack_from_to) == 0x670);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, lbr_select) == 0x770);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, ibs_fetch_ctl) == 0x778);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, ibs_fetch_linaddr) == 0x780);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, ibs_op_ctl) == 0x788);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, ibs_op_rip) == 0x790);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, ibs_op_data) == 0x798);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, ibs_op_data2) == 0x7A0);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, ibs_op_data3) == 0x7A8);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, ibs_dc_linaddr) == 0x7B0);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, bp_ibstgt_rip) == 0x7B8);
|
||||||
|
static_assert(offsetof(struct VMCBStateSaveArea, ic_ibs_extd_ctl) == 0x7C0);
|
||||||
|
static_assert(sizeof(struct VMCBStateSaveArea) == 0x800);
|
||||||
|
|
||||||
|
struct VMCB {
|
||||||
|
struct VMCBControlArea control_area;
|
||||||
|
struct VMCBStateSaveArea state_area;
|
||||||
|
u8 reserved_0 [0x400];
|
||||||
|
} __attribute__((packed));
|
||||||
|
static_assert(offsetof(struct VMCB, control_area) == 0x000);
|
||||||
|
static_assert(offsetof(struct VMCB, state_area) == 0x400);
|
||||||
|
static_assert(sizeof(struct VMCB) == 0x1000);
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/asm.h>
|
||||||
|
#include <host_state.h>
|
||||||
|
|
||||||
|
#define save_to_offset(val, REG) movq val , GUEST_ ## REG ## _OFFSET (% _ASM_ARG1 )
|
||||||
|
SYM_FUNC_START(capture_context)
|
||||||
|
#ifdef ENDBR
|
||||||
|
ENDBR
|
||||||
|
#endif
|
||||||
|
save_to_offset($0, RAX) /* save 0 for guest rax */
|
||||||
|
save_to_offset(%rbx, RBX)
|
||||||
|
save_to_offset(%rcx, RCX)
|
||||||
|
save_to_offset(%rdx, RDX)
|
||||||
|
save_to_offset(%rsi, RSI)
|
||||||
|
save_to_offset(%rdi, RDI)
|
||||||
|
save_to_offset(%rbp, RBP)
|
||||||
|
|
||||||
|
leaq 8(%rsp),%rax /* rsp after ret */
|
||||||
|
save_to_offset(%rax, RSP)
|
||||||
|
|
||||||
|
save_to_offset(%r8, R8)
|
||||||
|
save_to_offset(%r9, R9)
|
||||||
|
save_to_offset(%r10, R10)
|
||||||
|
save_to_offset(%r11, R11)
|
||||||
|
save_to_offset(%r12, R12)
|
||||||
|
save_to_offset(%r13, R13)
|
||||||
|
save_to_offset(%r14, R14)
|
||||||
|
save_to_offset(%r15, R15)
|
||||||
|
|
||||||
|
movq (%rsp), %rax /* return addr*/
|
||||||
|
save_to_offset(%rax, RIP)
|
||||||
|
|
||||||
|
pushfq
|
||||||
|
popq %rax /* rflags */
|
||||||
|
save_to_offset(%rax, RFLAGS)
|
||||||
|
|
||||||
|
mov $1, %rax;
|
||||||
|
RET
|
||||||
|
|
||||||
|
SYM_FUNC_END(capture_context)
|
||||||
@@ -0,0 +1,663 @@
|
|||||||
|
#include <linux/init.h> /* Needed for the macros */
|
||||||
|
#include <linux/module.h> /* Needed by all modules */
|
||||||
|
#include <linux/printk.h> /* Needed for pr_info() */
|
||||||
|
#include <linux/string.h> /* for memset() and memcpy() */
|
||||||
|
#include <linux/bits.h>
|
||||||
|
#include <linux/version.h>
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 11, 0)
|
||||||
|
#include <linux/cpuhplock.h>
|
||||||
|
#else
|
||||||
|
#include <linux/cpu.h>
|
||||||
|
#endif
|
||||||
|
#include <linux/suspend.h>
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <asm/desc.h>
|
||||||
|
#include <asm/msr.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
|
||||||
|
#include <host_state.h>
|
||||||
|
#include <vmcb_layout.h>
|
||||||
|
|
||||||
|
#define MSR_PM_BASE1 0x00000000
|
||||||
|
#define MSR_PM_BASE2 0xc0000000
|
||||||
|
#define MSR_PM_BASE3 0xc0010000
|
||||||
|
#define SVM_MSR_VM_HSAVE_PA 0xc0010117
|
||||||
|
|
||||||
|
#define UNLOAD_HV_MAGIC 0x40067420
|
||||||
|
|
||||||
|
#define SVM_SUPPORT_LEAF 0x80000001
|
||||||
|
#define SVM_SUPPORT_BIT 2
|
||||||
|
|
||||||
|
#define SVM_MSR_VM_CR 0xc0010114
|
||||||
|
#define VM_CR_SVMDIS_BIT 4
|
||||||
|
|
||||||
|
#define VMEXIT_CPUID 0x72
|
||||||
|
#define VMEXIT_MSRPROT 0x7C
|
||||||
|
|
||||||
|
/* VECTOR 8 bits = 0x0D (GP) */
|
||||||
|
/* TYPE 3 bits = 0x3 (Fault) */
|
||||||
|
/* EV 1 bit = 0x1 (Error Code Valid) */
|
||||||
|
/* reserved 19 bits */
|
||||||
|
/* V 1 bit = 0x1 (Valid) */
|
||||||
|
/* ERRORCODE 32 bits = 0x0 */
|
||||||
|
#define GP0_EVENTINJ (0x0D | (0x3 << 8) | (0x1 << 11) | (0x1 << 31))
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef page_to_phys
|
||||||
|
#define page_to_phys(page) PFN_PHYS(page_to_pfn(page))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The hypervisor doesn't handle nested virtualization, so attempting to
|
||||||
|
* virtualize a kernel currently using virtualization features will probably
|
||||||
|
* result in an immediate crash. If you know better you can tell the module
|
||||||
|
* to attempt the virtualization anyway */
|
||||||
|
static int ignore_svm_enabled = 0;
|
||||||
|
module_param(ignore_svm_enabled, int, 0);
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
struct page* msrpm_page;
|
||||||
|
u64 msrpm_pa;
|
||||||
|
bool prev_cpuid_fault_cap;
|
||||||
|
bool prev_svm_enabled;
|
||||||
|
} shared_data;
|
||||||
|
|
||||||
|
|
||||||
|
inline static void vmsave(u64 vmcb_pa) {
|
||||||
|
asm volatile ("vmsave" : : "a" (vmcb_pa) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void vmload(u64 vmcb_pa) {
|
||||||
|
asm volatile ("vmload" : : "a" (vmcb_pa) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void do_cpuid(u32* eax, u32* ebx, u32* ecx, u32* edx) {
|
||||||
|
asm volatile ("cpuid"
|
||||||
|
: "+a"(*eax), "=b"(*ebx), "+c"(*ecx), "=d"(*edx)
|
||||||
|
:
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void do_cpuid_leaf(u32 leaf, u32* eax, u32* ebx,
|
||||||
|
u32* ecx, u32* edx) {
|
||||||
|
asm volatile ("cpuid"
|
||||||
|
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
||||||
|
: "a"(leaf)
|
||||||
|
: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void do_wrmsr(u32 msr, u64 val) {
|
||||||
|
asm volatile ("wrmsr" : : "c"(msr), "a"((u32)val), "d" ((u32)(val >> 32)) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static u64 do_rdmsr(u32 msr) {
|
||||||
|
u32 low, high;
|
||||||
|
asm volatile ("rdmsr" : "=a"(low), "=d" (high) : "c"(msr));
|
||||||
|
return low | ((u64)high) << 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Raw writes and reads for cr registers. The kernel has it's own safer
|
||||||
|
* versions, however, all the writes we do should use values provided by the
|
||||||
|
* kernel, so these consistent raw versions are cleaner to use. */
|
||||||
|
#define define_cr_ops(cr) \
|
||||||
|
inline static u64 do_read_ ## cr (void) {\
|
||||||
|
u64 val; \
|
||||||
|
asm volatile ("movq %%" #cr ", %0" : "=r" (val) : :); \
|
||||||
|
return val; \
|
||||||
|
} \
|
||||||
|
inline static void do_write_ ## cr (u64 val) {\
|
||||||
|
asm volatile ("movq %0, %%" #cr : :"r" (val) :); \
|
||||||
|
}
|
||||||
|
define_cr_ops(cr0);
|
||||||
|
define_cr_ops(cr2);
|
||||||
|
define_cr_ops(cr3);
|
||||||
|
define_cr_ops(cr4);
|
||||||
|
|
||||||
|
/* Checks the relevant CPUID bits and MSR registers to determine SVM support
|
||||||
|
* since the hypervisor doesn't use features like NPT or decode assists,
|
||||||
|
* very few checks are needed */
|
||||||
|
static bool check_svm_support(void) {
|
||||||
|
u32 eax, ebx, ecx, edx;
|
||||||
|
|
||||||
|
/* check for "AuthenticAMD" on leaf 0 */
|
||||||
|
do_cpuid_leaf(0, &eax, &ebx, &ecx, &edx);
|
||||||
|
if (!(ebx == 'htuA' && edx == 'itne' && ecx == 'DMAc'))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* check for SVM support */
|
||||||
|
do_cpuid_leaf(SVM_SUPPORT_LEAF, &eax, &ebx, &ecx, &edx);
|
||||||
|
if (!(ecx & (1U << SVM_SUPPORT_BIT)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* check if SVM is disabled by the BIOS */
|
||||||
|
if (do_rdmsr(SVM_MSR_VM_CR) & BIT_ULL(VM_CR_SVMDIS_BIT))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* capture_context saves all GPR's, as well as RIP and RFLAGS as they are at
|
||||||
|
* it's return, except for RAX, which is saved as 0, but returned as 1 */
|
||||||
|
noinline_for_stack u64 capture_context(struct InitialContext* registers);
|
||||||
|
|
||||||
|
/* run_vm repeatedly runs the VMRUN instruction, effectively continuing to
|
||||||
|
* run the guest (the OS), when an intercepted event happens, it calls the
|
||||||
|
* handle_vm_exit function with the current state of the guest. If the call
|
||||||
|
* returns a non-zero value it begins the process of devirtualizing the
|
||||||
|
* processor */
|
||||||
|
__attribute__((noreturn)) void run_vm(struct ProcessorStatus* status);
|
||||||
|
|
||||||
|
/* called when the guest would execute a CPUID instruction*/
|
||||||
|
static u64 handle_cpuid(struct ProcessorStatus* status) {
|
||||||
|
u32 eax = status->guest_registers.rax;
|
||||||
|
u32 ebx;
|
||||||
|
u32 ecx = status->guest_registers.rcx;
|
||||||
|
u32 edx;
|
||||||
|
if(status->vmcb.state_area.cpl == 0) {
|
||||||
|
switch (eax) {
|
||||||
|
case UNLOAD_HV_MAGIC:
|
||||||
|
status->vmcb.state_area.rip += 2;
|
||||||
|
return 1; /* tell the hypervisor to devirtualize the processor */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(status->cpuid_fault) { /* if CPUID should fault */
|
||||||
|
status->vmcb.control_area.eventinj = GP0_EVENTINJ; /* inject GP */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* otherwise, run CPUID and increase RIP */
|
||||||
|
do_cpuid(&eax, &ebx, &ecx, &edx);
|
||||||
|
status->guest_registers.rax = eax;
|
||||||
|
status->guest_registers.rbx = ebx;
|
||||||
|
status->guest_registers.rcx = ecx;
|
||||||
|
status->guest_registers.rdx = edx;
|
||||||
|
status->vmcb.state_area.rip += 2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called when the guest would execute a read or write to a protected MSR */
|
||||||
|
static u64 handle_msr(struct ProcessorStatus* status) {
|
||||||
|
/* the msr the guest is trying to access */
|
||||||
|
u32 msr = status->guest_registers.rcx;
|
||||||
|
|
||||||
|
bool write_access = (status->vmcb.control_area.exitinfo1 != 0);
|
||||||
|
/* to emulate cpuid_fault, writes and reads to the corresponding MSR are
|
||||||
|
* intercepted */
|
||||||
|
if (write_access) {
|
||||||
|
u64 value = (status->guest_registers.rdx << 32) |
|
||||||
|
(u32)status->guest_registers.rax;
|
||||||
|
#ifdef MSR_K7_HWCR_CPUID_USER_DIS_BIT
|
||||||
|
/* If the MSR to enable / disable cpuid_fault is being written to */
|
||||||
|
if(msr == MSR_K7_HWCR) {
|
||||||
|
/* update whether the hypervisor should inject a fault on CPUID */
|
||||||
|
status->cpuid_fault = value & BIT_ULL(MSR_K7_HWCR_CPUID_USER_DIS_BIT);
|
||||||
|
/* write the value to the register, with the cpuid_fault bit clear */
|
||||||
|
do_wrmsr(msr, value & ~BIT_ULL(MSR_K7_HWCR_CPUID_USER_DIS_BIT));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Older kernels will attempt to enable cpuid_fault using the intel
|
||||||
|
* MSR */
|
||||||
|
if(msr == MSR_MISC_FEATURES_ENABLES) {
|
||||||
|
status->cpuid_fault = value & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
/* If we don't care about the MSR, do the write directly */
|
||||||
|
do_wrmsr(msr, value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
u64 value;
|
||||||
|
#ifdef MSR_K7_HWCR_CPUID_USER_DIS_BIT
|
||||||
|
/* If the MSR to enable / disable cpuid_fault is being read */
|
||||||
|
if(msr == MSR_K7_HWCR) {
|
||||||
|
value = do_rdmsr(msr);
|
||||||
|
/* reflect the current cpuid_fault status to the guest */
|
||||||
|
if(status->cpuid_fault)
|
||||||
|
value |= BIT_ULL(MSR_K7_HWCR_CPUID_USER_DIS_BIT);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Older kernels will attempt to enable cpuid_faulting using the intel
|
||||||
|
* MSR */
|
||||||
|
if(msr == MSR_MISC_FEATURES_ENABLES) {
|
||||||
|
value = 0;
|
||||||
|
if(status->cpuid_fault)
|
||||||
|
value |= MSR_MISC_FEATURES_ENABLES_CPUID_FAULT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else {
|
||||||
|
/* If we don't care about the MSR, do the read directly */
|
||||||
|
value = do_rdmsr(msr);
|
||||||
|
}
|
||||||
|
status->guest_registers.rax = (u32)value;
|
||||||
|
status->guest_registers.rdx = (u32)(value >> 32);
|
||||||
|
}
|
||||||
|
status->vmcb.state_area.rip += 2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* consistent functions to write segment selectors */
|
||||||
|
#define define_sel_ops(sel) \
|
||||||
|
inline static u64 read_ ## sel ## _sel(void) {\
|
||||||
|
u16 sel; \
|
||||||
|
asm volatile ("movw %%" #sel ", %0" : "=r" (sel) : :); \
|
||||||
|
return sel; \
|
||||||
|
} \
|
||||||
|
inline static void write_ ## sel ## _sel(u16 sel) {\
|
||||||
|
asm volatile ("movw %0, %%" #sel : :"r" (sel) :); \
|
||||||
|
}
|
||||||
|
define_sel_ops(ds);
|
||||||
|
define_sel_ops(es);
|
||||||
|
define_sel_ops(ss);
|
||||||
|
inline static u64 read_cs_sel(void) {
|
||||||
|
u16 cs;
|
||||||
|
asm volatile("movw %%cs, %0" : "=r"(cs) : :);
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
/* a direct move into cs is not a valid instruction, so the value is written
|
||||||
|
* via a far jump */
|
||||||
|
inline static void write_cs_sel(u16 cs) {
|
||||||
|
asm volatile("movzwq %0,%%rax\n\t"
|
||||||
|
"pushq %%rax\n\t"
|
||||||
|
"leaq curr_ip(%%rip),%%rax\n\t"
|
||||||
|
"pushq %%rax\n\t"
|
||||||
|
"lretq\n\t"
|
||||||
|
"curr_ip:": : "r"(cs) : "rax");
|
||||||
|
};
|
||||||
|
|
||||||
|
/* To end the virtualization the host needs to put itself the guest was just
|
||||||
|
* in, this effectively does the opposite to setup_guest_state */
|
||||||
|
static void restore_host_state(struct ProcessorStatus* status) {
|
||||||
|
struct VMCB* guest_vmcb = &status->vmcb;
|
||||||
|
struct desc_ptr gdt_ptr;
|
||||||
|
struct desc_ptr idt_ptr;
|
||||||
|
/* Load other state that might have changed */
|
||||||
|
vmload(status->vmcb_pa);
|
||||||
|
|
||||||
|
/* Restore the hsave address before the processor was virtualized */
|
||||||
|
do_wrmsr(SVM_MSR_VM_HSAVE_PA, status->prev_hsave_pa);
|
||||||
|
|
||||||
|
do_wrmsr(MSR_EFER, guest_vmcb->state_area.efer);
|
||||||
|
|
||||||
|
idt_ptr.address = guest_vmcb->state_area.idtr.base;
|
||||||
|
idt_ptr.size = guest_vmcb->state_area.idtr.limit;
|
||||||
|
gdt_ptr.address = guest_vmcb->state_area.gdtr.base;
|
||||||
|
gdt_ptr.size = guest_vmcb->state_area.gdtr.limit;
|
||||||
|
|
||||||
|
/* Restore gdt and idt. Done for correctness */
|
||||||
|
native_load_gdt(&gdt_ptr);
|
||||||
|
native_load_idt(&idt_ptr);
|
||||||
|
|
||||||
|
/* Load segment selectors from the guest. Also for correctness */
|
||||||
|
write_es_sel(guest_vmcb->state_area.es.selector);
|
||||||
|
write_ss_sel(guest_vmcb->state_area.ss.selector);
|
||||||
|
write_ds_sel(guest_vmcb->state_area.ds.selector);
|
||||||
|
write_cs_sel(guest_vmcb->state_area.cs.selector);
|
||||||
|
|
||||||
|
/* run_vm will resume running the OS by setting this rip and rsp */
|
||||||
|
status->guest_registers.rax = guest_vmcb->state_area.rip;
|
||||||
|
status->guest_registers.rsp = guest_vmcb->state_area.rsp;
|
||||||
|
|
||||||
|
/* will be used by the OS to cleanup the per processor data */
|
||||||
|
status->guest_registers.rbx = (u64)status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Everytime an intercepted instruction is excecuted (currently only
|
||||||
|
* wrmsr/rdmsr to the cpuid_fault register, cpuid and runvm (required by
|
||||||
|
* the processor)), the guest's state is saved and the hypervisor calls
|
||||||
|
* this function */
|
||||||
|
u64 handle_vm_exit(struct ProcessorStatus* status) {
|
||||||
|
status->guest_registers.rsp = status->vmcb.state_area.rsp;
|
||||||
|
status->guest_registers.rax = status->vmcb.state_area.rax;
|
||||||
|
|
||||||
|
u64 exitcode = status->vmcb.control_area.exitcode;
|
||||||
|
u64 result = 0;
|
||||||
|
switch(exitcode) {
|
||||||
|
case VMEXIT_CPUID:
|
||||||
|
result = handle_cpuid(status);
|
||||||
|
break;
|
||||||
|
case VMEXIT_MSRPROT:
|
||||||
|
result = handle_msr(status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(result) { /* begin the devirtualization process */
|
||||||
|
restore_host_state(status);
|
||||||
|
}
|
||||||
|
status->vmcb.state_area.rsp = status->guest_registers.rsp;
|
||||||
|
status->vmcb.state_area.rax = status->guest_registers.rax;
|
||||||
|
return result; /* tell run_vm if it should keep running the guest */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Used to initialize the segment registers (cs, ds, es, ss) in the VMCB */
|
||||||
|
static void set_descriptor_from_gdt(struct desc_ptr* gdtr, u16 selector,
|
||||||
|
struct SegmentDescriptor* desc) {
|
||||||
|
desc->selector = selector;
|
||||||
|
|
||||||
|
u64 idx = selector & ~0b111; /* Mask out the TI and RPL bits */
|
||||||
|
|
||||||
|
if(!idx) {
|
||||||
|
desc->attrib = 0;
|
||||||
|
desc->limit = 0;
|
||||||
|
desc->base = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the 8 bytes of the descriptor from the gdt, there's also 16-byte
|
||||||
|
* descriptors (e.g. TSS, LDT), but the function is not used for them, so
|
||||||
|
* they're not handled */
|
||||||
|
u64 raw = *(u64*) (gdtr->address + idx);
|
||||||
|
|
||||||
|
/* Concatenate the attribute bits */
|
||||||
|
desc->attrib = ((raw & (0xFFL << 40)) >> 40) |
|
||||||
|
((raw & (0xFL << 52)) >> 44);
|
||||||
|
/* Concatenate the limit bits */
|
||||||
|
desc->limit = (raw & 0xFFFF) | ((raw & (0xFL << 48)) >> 32);
|
||||||
|
/* If the granularity is 4kb, store the effective limit */
|
||||||
|
if(raw & (0x1L << 55)) desc->limit = (desc->limit << 12) | 0xFFFL;
|
||||||
|
/* Concatenate the base address bits */
|
||||||
|
desc->base = ((raw & (0xFFFFL << 16)) >> 16) |
|
||||||
|
((raw & (0xFFL << 32)) >> 16) |
|
||||||
|
((raw & (0xFFL << 56)) >> 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This setups all of the state needed to run a vm with the current status
|
||||||
|
* of the processor */
|
||||||
|
static void setup_guest_state(struct page* host_status_page,
|
||||||
|
struct InitialContext* initial_context) {
|
||||||
|
u64 host_status_pa = page_to_phys(host_status_page);
|
||||||
|
u64 guest_vmcb_pa = host_status_pa + HOST_VMCB_OFFSET;
|
||||||
|
u64 host_vmcb_pa = host_status_pa + HOST_HOST_VMCB_OFFSET;
|
||||||
|
u64 host_save_pa = host_status_pa + HOST_HOST_SAVE_OFFSET;
|
||||||
|
|
||||||
|
struct ProcessorStatus* host_status = page_address(host_status_page);
|
||||||
|
host_status->vmcb_pa = guest_vmcb_pa;
|
||||||
|
host_status->host_vmcb_pa = host_vmcb_pa;
|
||||||
|
|
||||||
|
/* used to cleanup after the processor is devirtualized */
|
||||||
|
host_status->page_ptr = host_status_page;
|
||||||
|
|
||||||
|
host_status->guest_registers = initial_context->regs;
|
||||||
|
struct VMCB* guest_vmcb = &host_status->vmcb;
|
||||||
|
|
||||||
|
struct desc_ptr gdt_ptr;
|
||||||
|
struct desc_ptr idt_ptr;
|
||||||
|
|
||||||
|
native_store_gdt(&gdt_ptr);
|
||||||
|
store_idt(&idt_ptr);
|
||||||
|
|
||||||
|
/* intercept MSRs defined by MSR prot */
|
||||||
|
guest_vmcb->control_area.intercept_vector3.msr_prot = 1;
|
||||||
|
guest_vmcb->control_area.msrpm_base_pa = shared_data.msrpm_pa;
|
||||||
|
|
||||||
|
/* intercept the CPUID instruction */
|
||||||
|
guest_vmcb->control_area.intercept_vector3.cpuid_inst = 1;
|
||||||
|
|
||||||
|
/* intercept the VMRUN instruction (required to run VMRUN) */
|
||||||
|
guest_vmcb->control_area.intercept_vector4.vmrun_inst = 1;
|
||||||
|
|
||||||
|
/* the guest uses it's own address space, 1 is the safest value to use */
|
||||||
|
guest_vmcb->control_area.guest_asid = 1;
|
||||||
|
|
||||||
|
u32 eax, ebx, ecx, edx;
|
||||||
|
do_cpuid_leaf(0x80000008, &eax, &ebx, &ecx, &edx);
|
||||||
|
if(ebx & (1 << 3)) {
|
||||||
|
do_cpuid_leaf(0x8000000a, &eax, &ebx, &ecx, &edx);
|
||||||
|
if(edx & (1 << 24)) {
|
||||||
|
guest_vmcb->control_area.virtualization_control0.invlpg_tlbsync_enable = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
guest_vmcb->state_area.gdtr.base = gdt_ptr.address;
|
||||||
|
guest_vmcb->state_area.gdtr.limit = gdt_ptr.size;
|
||||||
|
guest_vmcb->state_area.idtr.base = idt_ptr.address;
|
||||||
|
guest_vmcb->state_area.idtr.limit = idt_ptr.size;
|
||||||
|
|
||||||
|
u16 cs_selector = read_cs_sel();
|
||||||
|
set_descriptor_from_gdt(&gdt_ptr, cs_selector,
|
||||||
|
&guest_vmcb->state_area.cs);
|
||||||
|
u16 ds_selector = read_ds_sel();
|
||||||
|
set_descriptor_from_gdt(&gdt_ptr, ds_selector,
|
||||||
|
&guest_vmcb->state_area.ds);
|
||||||
|
u16 es_selector = read_es_sel();
|
||||||
|
set_descriptor_from_gdt(&gdt_ptr, es_selector,
|
||||||
|
&guest_vmcb->state_area.es);
|
||||||
|
u16 ss_selector = read_ss_sel();
|
||||||
|
set_descriptor_from_gdt(&gdt_ptr, ss_selector,
|
||||||
|
&guest_vmcb->state_area.ss);
|
||||||
|
|
||||||
|
guest_vmcb->state_area.efer = do_rdmsr(MSR_EFER);
|
||||||
|
guest_vmcb->state_area.cr0 = do_read_cr0();
|
||||||
|
guest_vmcb->state_area.cr2 = do_read_cr2();
|
||||||
|
guest_vmcb->state_area.cr3 = do_read_cr3();
|
||||||
|
guest_vmcb->state_area.cr4 = do_read_cr4();
|
||||||
|
|
||||||
|
guest_vmcb->state_area.rflags = initial_context->rflags;
|
||||||
|
guest_vmcb->state_area.rsp = initial_context->regs.rsp;
|
||||||
|
guest_vmcb->state_area.rip = initial_context->rip;
|
||||||
|
guest_vmcb->state_area.rax = initial_context->regs.rax;
|
||||||
|
|
||||||
|
vmsave(guest_vmcb_pa);
|
||||||
|
|
||||||
|
/* Save the hsave address before the hypervisor is loaded */
|
||||||
|
/* (If the kvm_amd kernel module is loaded, this value will already be
|
||||||
|
* setup and changing it and trying to run a kvm vm will crash the OS) */
|
||||||
|
host_status->prev_hsave_pa = do_rdmsr(SVM_MSR_VM_HSAVE_PA);
|
||||||
|
do_wrmsr(SVM_MSR_VM_HSAVE_PA, host_save_pa);
|
||||||
|
|
||||||
|
/* save another copy of the host state, used to provide a more consistent
|
||||||
|
* host state at vmexit */
|
||||||
|
vmsave(host_vmcb_pa);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int virtualize_processor(void* processor_number) {
|
||||||
|
struct page* host_status_page;
|
||||||
|
int order = get_order(sizeof(struct ProcessorStatus));
|
||||||
|
host_status_page = alloc_pages(GFP_KERNEL, order);
|
||||||
|
if (!host_status_page)
|
||||||
|
goto host_status_page_failed;
|
||||||
|
|
||||||
|
unsigned long flags;
|
||||||
|
get_cpu();
|
||||||
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
memset(page_address(host_status_page), 0, PAGE_SIZE * (1 << order));
|
||||||
|
|
||||||
|
struct InitialContext context;
|
||||||
|
|
||||||
|
|
||||||
|
/* Capture the context to be used to initialize the guest, since it
|
||||||
|
* returns 1 but the stored state has 0 as it's return, when the guest
|
||||||
|
* starts execution at the stored state it will not enter into the if.
|
||||||
|
* */
|
||||||
|
if(capture_context(&context)) {
|
||||||
|
|
||||||
|
do_wrmsr(MSR_EFER, do_rdmsr(MSR_EFER) | EFER_SVME); /* Enable SVME */
|
||||||
|
|
||||||
|
setup_guest_state(host_status_page, &context);
|
||||||
|
struct ProcessorStatus* host_status = page_address(host_status_page);
|
||||||
|
|
||||||
|
/* Kinda ugly, effectively sets a CR3 for the host that will
|
||||||
|
* always be safe to access the hypervisor's code from
|
||||||
|
* */
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 9, 0)
|
||||||
|
leave_mm();
|
||||||
|
#else
|
||||||
|
leave_mm(smp_processor_id());
|
||||||
|
#endif
|
||||||
|
run_vm(host_status);
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only the guest should run this code */
|
||||||
|
put_cpu();
|
||||||
|
|
||||||
|
pr_info("Processor %d virtualized\n", (u32)(u64)processor_number);
|
||||||
|
return 0;
|
||||||
|
host_status_page_failed:
|
||||||
|
local_irq_restore(flags);
|
||||||
|
put_cpu();
|
||||||
|
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_svm_on_cpu(void*) {
|
||||||
|
return do_rdmsr(MSR_EFER) & EFER_SVME;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool check_svm_status(void) {
|
||||||
|
u32 svm_enabled = 0;
|
||||||
|
cpus_read_lock();
|
||||||
|
u32 cpu;
|
||||||
|
for_each_online_cpu(cpu) {
|
||||||
|
svm_enabled |= smp_call_on_cpu(cpu, check_svm_on_cpu, NULL, true);
|
||||||
|
}
|
||||||
|
cpus_read_unlock();
|
||||||
|
return svm_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int devirtualize_processor(void* processor_number) {
|
||||||
|
int order = get_order(sizeof(struct ProcessorStatus));
|
||||||
|
unsigned long flags;
|
||||||
|
get_cpu();
|
||||||
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
u64 rax = UNLOAD_HV_MAGIC;
|
||||||
|
u64 rbx, rcx, rdx;
|
||||||
|
asm volatile("cpuid":"+a"(rax),"=b"(rbx),"=c"(rcx),"=d"(rdx)::"memory");
|
||||||
|
struct ProcessorStatus* status = NULL;
|
||||||
|
|
||||||
|
if(rax != UNLOAD_HV_MAGIC) {
|
||||||
|
status = (struct ProcessorStatus*)rbx;
|
||||||
|
struct VMCB* guest_vmcb = &status->vmcb;
|
||||||
|
|
||||||
|
do_write_cr3(guest_vmcb->state_area.cr3);
|
||||||
|
do_write_cr4(guest_vmcb->state_area.cr4);
|
||||||
|
do_write_cr2(guest_vmcb->state_area.cr2);
|
||||||
|
do_write_cr0(guest_vmcb->state_area.cr0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!shared_data.prev_svm_enabled)
|
||||||
|
do_wrmsr(MSR_EFER, do_rdmsr(MSR_EFER) & ~EFER_SVME);
|
||||||
|
|
||||||
|
local_irq_restore(flags);
|
||||||
|
put_cpu();
|
||||||
|
if(status)__free_pages(status->page_ptr, order);
|
||||||
|
|
||||||
|
|
||||||
|
pr_info("Processor %d devirtualized\n", (u32)(u64)processor_number);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called when a Power Management (e.g. suspend) event is about to happen */
|
||||||
|
static int handle_pm_notification(struct notifier_block* nb, unsigned long action, void *data) {
|
||||||
|
|
||||||
|
if(action == PM_HIBERNATION_PREPARE || action == PM_SUSPEND_PREPARE) {
|
||||||
|
/* on suspend or hibernation svm is disabled, so
|
||||||
|
* all processors need to be devirtualized */
|
||||||
|
cpus_read_lock();
|
||||||
|
u32 cpu;
|
||||||
|
for_each_online_cpu(cpu) {
|
||||||
|
smp_call_on_cpu(cpu, devirtualize_processor, (void*)(u64)cpu, true);
|
||||||
|
}
|
||||||
|
cpus_read_unlock();
|
||||||
|
/* return the cpuid_fault bit capability to it's previous value */
|
||||||
|
if(!shared_data.prev_cpuid_fault_cap)
|
||||||
|
clear_bit(X86_FEATURE_CPUID_FAULT,
|
||||||
|
(unsigned long *)(boot_cpu_data.x86_capability));
|
||||||
|
}
|
||||||
|
if(action == PM_POST_HIBERNATION || action == PM_POST_SUSPEND) {
|
||||||
|
/* revirtualize all processors after suspend or hibernation */
|
||||||
|
cpus_read_lock();
|
||||||
|
u32 cpu;
|
||||||
|
for_each_online_cpu(cpu) {
|
||||||
|
smp_call_on_cpu(cpu, virtualize_processor, (void*)(u64)cpu, true);
|
||||||
|
}
|
||||||
|
cpus_read_unlock();
|
||||||
|
shared_data.prev_cpuid_fault_cap = test_bit(X86_FEATURE_CPUID_FAULT,
|
||||||
|
(unsigned long *)(boot_cpu_data.x86_capability));
|
||||||
|
set_bit(X86_FEATURE_CPUID_FAULT,
|
||||||
|
(unsigned long *)(boot_cpu_data.x86_capability));
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct notifier_block pm_notifier = {
|
||||||
|
.notifier_call = handle_pm_notification
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init init_emulation(void) {
|
||||||
|
if (!check_svm_support()) {
|
||||||
|
pr_info("Processor not supported\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
shared_data.prev_svm_enabled = check_svm_status();
|
||||||
|
|
||||||
|
if(shared_data.prev_svm_enabled && !ignore_svm_enabled) {
|
||||||
|
pr_info("SVM already enabled\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
shared_data.msrpm_page = alloc_pages(GFP_KERNEL, 1);
|
||||||
|
if (!shared_data.msrpm_page)
|
||||||
|
goto msrpm_failed;
|
||||||
|
shared_data.msrpm_pa = page_to_phys(shared_data.msrpm_page);
|
||||||
|
|
||||||
|
memset(page_address(shared_data.msrpm_page), 0, 0x2000);
|
||||||
|
unsigned char* section_1_start = (unsigned char*)
|
||||||
|
page_address(shared_data.msrpm_page);
|
||||||
|
unsigned char* section_3_start = (unsigned char*)
|
||||||
|
page_address(shared_data.msrpm_page) + 0x1000;
|
||||||
|
|
||||||
|
#ifdef MSR_K7_HWCR_CPUID_USER_DIS_BIT
|
||||||
|
set_bit((MSR_K7_HWCR - MSR_PM_BASE3) * 2,
|
||||||
|
(unsigned long*) section_3_start);
|
||||||
|
set_bit((MSR_K7_HWCR - MSR_PM_BASE3) * 2 + 1,
|
||||||
|
(unsigned long*) section_3_start);
|
||||||
|
#else /* on older kernels intercept the intel register instead */
|
||||||
|
set_bit((MSR_MISC_FEATURES_ENABLES - MSR_PM_BASE1) * 2,
|
||||||
|
(unsigned long*) section_1_start);
|
||||||
|
set_bit((MSR_MISC_FEATURES_ENABLES - MSR_PM_BASE1) * 2 + 1,
|
||||||
|
(unsigned long*) section_1_start);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cpus_read_lock();
|
||||||
|
u32 cpu;
|
||||||
|
for_each_online_cpu(cpu) {
|
||||||
|
smp_call_on_cpu(cpu, virtualize_processor, (void*)(u64)cpu, true);
|
||||||
|
}
|
||||||
|
cpus_read_unlock();
|
||||||
|
shared_data.prev_cpuid_fault_cap = test_bit(X86_FEATURE_CPUID_FAULT,
|
||||||
|
(unsigned long *)(boot_cpu_data.x86_capability));
|
||||||
|
set_bit(X86_FEATURE_CPUID_FAULT,
|
||||||
|
(unsigned long *)(boot_cpu_data.x86_capability));
|
||||||
|
|
||||||
|
register_pm_notifier(&pm_notifier);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
msrpm_failed:
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit deinit_emulation(void) {
|
||||||
|
unregister_pm_notifier(&pm_notifier);
|
||||||
|
if(!shared_data.prev_cpuid_fault_cap)
|
||||||
|
clear_bit(X86_FEATURE_CPUID_FAULT,
|
||||||
|
(unsigned long *)(boot_cpu_data.x86_capability));
|
||||||
|
cpus_read_lock();
|
||||||
|
u32 cpu;
|
||||||
|
for_each_online_cpu(cpu) {
|
||||||
|
smp_call_on_cpu(cpu, devirtualize_processor, (void*)(u64)cpu, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
cpus_read_unlock();
|
||||||
|
if (shared_data.msrpm_page)
|
||||||
|
__free_pages(shared_data.msrpm_page, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module_init(init_emulation);
|
||||||
|
module_exit(deinit_emulation);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
#include <linux/linkage.h>
|
||||||
|
#include <asm/asm.h>
|
||||||
|
#include <host_state.h>
|
||||||
|
|
||||||
|
#define save_to_offset_from(val, off, from) movq val, off -(HOST_STACK_OFFSET + HOST_STACK_SIZE) (from)
|
||||||
|
#define mov_from_offset_from(off, reg, from) movq off -(HOST_STACK_OFFSET + HOST_STACK_SIZE) (from), reg
|
||||||
|
#define save_to_offset(val, off) save_to_offset_from(val, off, %rsp)
|
||||||
|
#define mov_from_offset(off, reg) mov_from_offset_from(off, reg, %rsp)
|
||||||
|
#define save_to_reg_from(val, REG, from) save_to_offset_from(val, HOST_REGISTER_OFFSET + GUEST_ ## REG ## _OFFSET, from)
|
||||||
|
#define mov_from_reg_from(REG, reg, from) mov_from_offset_from(HOST_REGISTER_OFFSET + GUEST_ ## REG ## _OFFSET, reg, from)
|
||||||
|
#define save_to_reg(val, REG) save_to_reg_from(val, REG, %rsp)
|
||||||
|
#define mov_from_reg(REG, reg) mov_from_reg_from(REG, reg, %rsp)
|
||||||
|
SYM_CODE_START(run_vm)
|
||||||
|
#ifdef ENDBR
|
||||||
|
ENDBR
|
||||||
|
#endif
|
||||||
|
leaq HOST_STACK_OFFSET + HOST_STACK_SIZE(%_ASM_ARG1), %rsp
|
||||||
|
|
||||||
|
vmloop:
|
||||||
|
mov_from_offset(HOST_HOST_VMCB_PA_OFFSET, %rax)
|
||||||
|
vmsave
|
||||||
|
|
||||||
|
mov_from_offset(HOST_VMCB_PA_OFFSET, %rax)
|
||||||
|
vmload
|
||||||
|
|
||||||
|
mov_from_reg(RBX, %rbx)
|
||||||
|
mov_from_reg(RCX, %rcx)
|
||||||
|
mov_from_reg(RDX, %rdx)
|
||||||
|
mov_from_reg(RSI, %rsi)
|
||||||
|
mov_from_reg(RDI, %rdi)
|
||||||
|
mov_from_reg(RBP, %rbp)
|
||||||
|
|
||||||
|
mov_from_reg(R8, %r8)
|
||||||
|
mov_from_reg(R9, %r9)
|
||||||
|
mov_from_reg(R10, %r10)
|
||||||
|
mov_from_reg(R11, %r11)
|
||||||
|
mov_from_reg(R12, %r12)
|
||||||
|
mov_from_reg(R13, %r13)
|
||||||
|
mov_from_reg(R14, %r14)
|
||||||
|
mov_from_reg(R15, %r15)
|
||||||
|
|
||||||
|
vmrun
|
||||||
|
|
||||||
|
vmsave
|
||||||
|
|
||||||
|
mov_from_offset(HOST_HOST_VMCB_PA_OFFSET, %rax)
|
||||||
|
vmload
|
||||||
|
|
||||||
|
save_to_reg(%rbx, RBX)
|
||||||
|
save_to_reg(%rcx, RCX)
|
||||||
|
save_to_reg(%rdx, RDX)
|
||||||
|
save_to_reg(%rsi, RSI)
|
||||||
|
save_to_reg(%rdi, RDI)
|
||||||
|
save_to_reg(%rbp, RBP)
|
||||||
|
|
||||||
|
save_to_reg(%r8, R8)
|
||||||
|
save_to_reg(%r9, R9)
|
||||||
|
save_to_reg(%r10, R10)
|
||||||
|
save_to_reg(%r11, R11)
|
||||||
|
save_to_reg(%r12, R12)
|
||||||
|
save_to_reg(%r13, R13)
|
||||||
|
save_to_reg(%r14, R14)
|
||||||
|
save_to_reg(%r15, R15)
|
||||||
|
|
||||||
|
leaq -HOST_STACK_SIZE(%rsp), %_ASM_ARG1
|
||||||
|
|
||||||
|
/* Save volatile XMM registers */
|
||||||
|
sub $0x80, %rsp
|
||||||
|
movaps %xmm0, 0x20(%rsp)
|
||||||
|
movaps %xmm1, 0x30(%rsp)
|
||||||
|
movaps %xmm2, 0x40(%rsp)
|
||||||
|
movaps %xmm3, 0x50(%rsp)
|
||||||
|
movaps %xmm4, 0x60(%rsp)
|
||||||
|
movaps %xmm5, 0x70(%rsp)
|
||||||
|
|
||||||
|
sub $0x8, %rsp
|
||||||
|
call handle_vm_exit
|
||||||
|
add $0x8, %rsp
|
||||||
|
|
||||||
|
/* Restore volatile XMM registers */
|
||||||
|
movaps 0x70(%rsp), %xmm5
|
||||||
|
movaps 0x60(%rsp), %xmm4
|
||||||
|
movaps 0x50(%rsp), %xmm3
|
||||||
|
movaps 0x40(%rsp), %xmm2
|
||||||
|
movaps 0x30(%rsp), %xmm1
|
||||||
|
movaps 0x20(%rsp), %xmm0
|
||||||
|
add $0x80, %rsp
|
||||||
|
|
||||||
|
test %rax, %rax
|
||||||
|
|
||||||
|
jz vmloop
|
||||||
|
|
||||||
|
mov_from_reg(RBX, %rbx) /* now holds rflags */
|
||||||
|
pushq %rbx
|
||||||
|
popfq
|
||||||
|
leaq (%rsp), %rax;
|
||||||
|
mov_from_reg(RBX, %rbx)
|
||||||
|
mov_from_reg(RCX, %rcx)
|
||||||
|
mov_from_reg(RDX, %rdx)
|
||||||
|
mov_from_reg(RSI, %rsi)
|
||||||
|
mov_from_reg(RDI, %rdi)
|
||||||
|
mov_from_reg(RBP, %rbp)
|
||||||
|
|
||||||
|
mov_from_reg(R8, %r8)
|
||||||
|
mov_from_reg(R9, %r9)
|
||||||
|
mov_from_reg(R10, %r10)
|
||||||
|
mov_from_reg(R11, %r11)
|
||||||
|
mov_from_reg(R12, %r12)
|
||||||
|
mov_from_reg(R13, %r13)
|
||||||
|
mov_from_reg(R14, %r14)
|
||||||
|
mov_from_reg(R15, %r15)
|
||||||
|
|
||||||
|
mov_from_reg(RSP, %rsp)
|
||||||
|
mov_from_reg_from(RAX, %rax, %rax) /* now holds rip */
|
||||||
|
|
||||||
|
stgi
|
||||||
|
pushq %rax
|
||||||
|
RET
|
||||||
|
|
||||||
|
|
||||||
|
SYM_CODE_END(run_vm)
|
||||||
Reference in New Issue
Block a user