@@ -5,13 +5,18 @@
struct kvm_config_arch {
const char *dump_dtb_filename;
+ unsigned int force_cntfrq;
bool aarch32_guest;
};
-#define OPT_ARCH_RUN(pfx, cfg) \
- pfx, \
- ARM_OPT_ARCH_RUN(cfg) \
- OPT_STRING('\0', "dump-dtb", &(cfg)->dump_dtb_filename, \
- ".dtb file", "Dump generated .dtb to specified file"),
+#define OPT_ARCH_RUN(pfx, cfg) \
+ pfx, \
+ ARM_OPT_ARCH_RUN(cfg) \
+ OPT_STRING('\0', "dump-dtb", &(cfg)->dump_dtb_filename, \
+ ".dtb file", "Dump generated .dtb to specified file"), \
+ OPT_UINTEGER('\0', "override-bad-firmware-cntfrq", &(cfg)->force_cntfrq,\
+ "Specify Generic Timer frequency in guest DT to " \
+ "work around buggy secure firmware *Firmware should be " \
+ "updated to program CNTFRQ correctly*"),
#endif /* ARM_COMMON__KVM_CONFIG_ARCH_H */
@@ -33,6 +33,8 @@ void timer__generate_fdt_nodes(void *fdt, struct kvm *kvm, int *irqs)
_FDT(fdt_begin_node(fdt, "timer"));
_FDT(fdt_property(fdt, "compatible", compatible, sizeof(compatible)));
_FDT(fdt_property(fdt, "interrupts", irq_prop, sizeof(irq_prop)));
+ if (kvm->cfg.arch.force_cntfrq > 0)
+ _FDT(fdt_property_cell(fdt, "clock-frequency", kvm->cfg.arch.force_cntfrq));
_FDT(fdt_end_node(fdt));
}