summaryrefslogtreecommitdiffstats
path: root/master/jmm/disable-all-pci-dma-on-boot
diff options
context:
space:
mode:
Diffstat (limited to 'master/jmm/disable-all-pci-dma-on-boot')
-rw-r--r--master/jmm/disable-all-pci-dma-on-boot85
1 files changed, 85 insertions, 0 deletions
diff --git a/master/jmm/disable-all-pci-dma-on-boot b/master/jmm/disable-all-pci-dma-on-boot
new file mode 100644
index 0000000..e330109
--- /dev/null
+++ b/master/jmm/disable-all-pci-dma-on-boot
@@ -0,0 +1,85 @@
+diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
+index fec513f..81048ef 100644
+--- a/grub-core/loader/i386/linux.c
++++ b/grub-core/loader/i386/linux.c
+@@ -34,6 +34,8 @@
+ #include <grub/i386/relocator.h>
+ #include <grub/i18n.h>
+ #include <grub/lib/cmdline.h>
++#include <grub/pci.h>
++
+
+ GRUB_MOD_LICENSE ("GPLv3+");
+
+@@ -495,6 +497,52 @@ static void fake_bios_data(void)
+
+ #endif
+
++static void stop_dma(void)
++{
++
++ auto int NESTED_FUNC_ATTR stop_card_dma (grub_pci_device_t dev,
++ grub_pci_id_t pciid);
++
++ int NESTED_FUNC_ATTR stop_card_dma (grub_pci_device_t dev,
++ grub_pci_id_t pciid)
++ {
++ grub_pci_address_t addr;
++ grub_uint16_t old_cmd,new_cmd;
++
++ (void) pciid;
++
++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
++
++ switch (grub_pci_read (addr) >> 24) {
++ case 0x00: /*unknown*/
++ case 0x03: /*GPU*/
++ case 0x05: /*memory*/
++ case 0x06: /*bridge*/
++ case 0x0b: /*cpu*/
++ break;
++ default: /*everything else gets dma turned off*/
++
++ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
++ old_cmd = grub_pci_read_word(addr);
++ new_cmd = old_cmd & ~GRUB_PCI_COMMAND_BUS_MASTER;
++ grub_pci_write_word(addr,new_cmd);
++
++#if 0
++ if (old_cmd!=new_cmd) {
++ grub_printf ("Disabled DMA on: %02x:%02x.%x %04x -> %04x\n",
++ grub_pci_get_bus (dev), grub_pci_get_device (dev),
++ grub_pci_get_function (dev), (int) old_cmd,(int) new_cmd);
++ }
++#endif
++ }
++
++ return 0;
++ }
++
++ grub_pci_iterate (stop_card_dma);
++}
++
++
+ static grub_err_t
+ grub_linux_boot (void)
+ {
+@@ -642,6 +690,7 @@ grub_linux_boot (void)
+ fake_bios_data();
+ #endif
+
++
+ #ifdef GRUB_MACHINE_EFI
+ {
+ grub_efi_uintn_t efi_desc_size;
+@@ -651,7 +700,9 @@ grub_linux_boot (void)
+ &efi_desc_size, &efi_desc_version);
+ if (err)
+ return err;
+-
++
++ stop_dma();
++
+ /* Note that no boot services are available from here. */
+ efi_mmap_target = real_mode_target
+ + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem);