diff --git a/qubes/config.py b/qubes/config.py
index da02dbb6..0c3d93a2 100644
--- a/qubes/config.py
+++ b/qubes/config.py
@@ -69,6 +69,8 @@ defaults = {
'hvm_memory': 400,
'kernelopts': "nopat",
'kernelopts_pcidevs': "nopat iommu=soft swiotlb=8192",
+ 'kernelopts_common': ('root=/dev/mapper/dmroot ro nomodeset console=hvc0 '
+ 'rd_NO_PLYMOUTH rd.plymouth.enable=0 plymouth.enable=0 '),
'dom0_update_check_interval': 6*3600,
diff --git a/qubes/tests/vm/qubesvm.py b/qubes/tests/vm/qubesvm.py
index 42988cfa..bb2f1202 100644
--- a/qubes/tests/vm/qubesvm.py
+++ b/qubes/tests/vm/qubesvm.py
@@ -867,6 +867,73 @@ class TC_90_QubesVM(QubesVMTestsMixin, qubes.tests.QubesTestCase):
self.assertXMLEqual(lxml.etree.XML(libvirt_xml),
lxml.etree.XML(expected))
+ def test_600_libvirt_xml_hvm_dom0_kernel_kernelopts(self):
+ expected = '''
+ test-inst-test
+ 7db78950-c467-4863-94d1-af59806384ea
+ 500
+ 400
+ 2
+
+
+
+
+
+
+
+
+ hvm
+
+ hvmloader
+
+
+ kernel specific options nopat
+
+
+
+
+
+
+
+
+ destroy
+ destroy
+ destroy
+
+
+
+
+
+
+
+
+ '''
+ my_uuid = '7db78950-c467-4863-94d1-af59806384ea'
+ vm = self.get_vm(uuid=my_uuid)
+ vm.netvm = None
+ vm.virt_mode = 'hvm'
+ vm.features['qrexec'] = True
+ with unittest.mock.patch('qubes.config.qubes_base_dir',
+ '/tmp/qubes-test'):
+ kernel_dir = '/tmp/qubes-test/vm-kernels/dummy'
+ os.makedirs(kernel_dir, exist_ok=True)
+ open(os.path.join(kernel_dir, 'vmlinuz'), 'w').close()
+ open(os.path.join(kernel_dir, 'initramfs'), 'w').close()
+ with open(os.path.join(kernel_dir,
+ 'default-kernelopts-common.txt'), 'w') as f:
+ f.write('kernel specific options \n')
+ self.addCleanup(shutil.rmtree, '/tmp/qubes-test')
+ vm.kernel = 'dummy'
+ libvirt_xml = vm.create_config_file()
+ self.assertXMLEqual(lxml.etree.XML(libvirt_xml),
+ lxml.etree.XML(expected))
+
def test_600_libvirt_xml_pvh(self):
expected = '''
test-inst-test
diff --git a/qubes/vm/qubesvm.py b/qubes/vm/qubesvm.py
index e41fcf93..5dbb2596 100644
--- a/qubes/vm/qubesvm.py
+++ b/qubes/vm/qubesvm.py
@@ -1983,6 +1983,25 @@ class QubesVM(qubes.vm.mix.net.NetVMMixin, qubes.vm.BaseVM):
return None
+ @property
+ def kernelopts_common(self):
+ '''Kernel options which should be used in addition to *kernelopts*
+ property.
+
+ This is specific to kernel (and initrd if any)
+ '''
+ if not self.kernel:
+ return ''
+ kernels_dir = self.storage.kernels_dir
+
+ kernelopts_path = os.path.join(kernels_dir,
+ 'default-kernelopts-common.txt')
+ if os.path.exists(kernelopts_path):
+ with open(kernelopts_path) as f_kernelopts:
+ return f_kernelopts.read().rstrip('\n\r')
+ else:
+ return qubes.config.defaults['kernelopts_common']
+
#
# helper methods
#
diff --git a/templates/libvirt/xen.xml b/templates/libvirt/xen.xml
index 8f3f7162..9176c9ae 100644
--- a/templates/libvirt/xen.xml
+++ b/templates/libvirt/xen.xml
@@ -47,7 +47,7 @@
{% if vm.features.check_with_template('no-default-kernelopts', False) -%}
{{ vm.kernelopts }}
{% else -%}
- root=/dev/mapper/dmroot ro nomodeset console=hvc0 rd_NO_PLYMOUTH rd.plymouth.enable=0 plymouth.enable=0 {{ vm.kernelopts }}
+ {{ vm.kernelopts_common }}{{ vm.kernelopts }}
{% endif -%}
{% endif %}
{% endblock %}