История изменений
Исправление Deleted, (текущая версия) :
Говнокостыльный патч для stable-2.1 (slow down time in qemu guest)
Исправление Deleted, :
Сначала я попробовать менять scale, как предложил mix_mix, но это приводило к зависанию при загрузке ядра в гостевой системе. Потом методом тыка я пришёл к этому:
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 7f9a074..31826ca 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -7,6 +7,8 @@
/* timers */
+#define SLOWDOWN 2
+
#define SCALE_MS 1000000
#define SCALE_US 1000
#define SCALE_NS 1
diff --git a/qemu-timer.c b/qemu-timer.c
index 00a5d35..2933473 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -550,13 +550,13 @@ int64_t qemu_clock_get_ns(QEMUClockType type)
switch (type) {
case QEMU_CLOCK_REALTIME:
- return get_clock();
+ return get_clock() / SLOWDOWN;
default:
case QEMU_CLOCK_VIRTUAL:
if (use_icount) {
- return cpu_get_icount();
+ return cpu_get_icount() / SLOWDOWN;
} else {
- return cpu_get_clock();
+ return cpu_get_clock() / SLOWDOWN;
}
case QEMU_CLOCK_HOST:
now = get_clock_realtime();
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index f9fcbca..3ce6499 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -448,13 +448,13 @@ typedef struct model_features_t {
* when KVM is enabled.
*/
static uint32_t kvm_default_features[FEATURE_WORDS] = {
- [FEAT_KVM] = (1 << KVM_FEATURE_CLOCKSOURCE) |
+ [FEAT_KVM] = /*(1 << KVM_FEATURE_CLOCKSOURCE) |*/
(1 << KVM_FEATURE_NOP_IO_DELAY) |
- (1 << KVM_FEATURE_CLOCKSOURCE2) |
+ /*(1 << KVM_FEATURE_CLOCKSOURCE2) |*/
(1 << KVM_FEATURE_ASYNC_PF) |
(1 << KVM_FEATURE_STEAL_TIME) |
- (1 << KVM_FEATURE_PV_EOI) |
- (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT),
+ (1 << KVM_FEATURE_PV_EOI) /*|
+ (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT)*/,
[FEAT_1_ECX] = CPUID_EXT_X2APIC,
};
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index ddedc73..3918cef 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -131,7 +131,7 @@ static const struct kvm_para_features {
int cap;
int feature;
} para_features[] = {
- { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
+ /*{ KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },*/
{ KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
{ KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
{ KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
- ping localhost (пакеты отправляются с большей паузой)
- date (время идёт в два раза медленнее =))
- watch -n1
Если не комментировать константы, связанные с KVM, то это работает только с выключенным KVM. Со включенным KVM видимо гостевая система работает с таймерами и прочим как-то в обход qemu.
Обратный отсчёт в isolinux со включенным KVM всегда работает правильно, даже с закомментированными KVM_FEATURE_CLOCKSOURCE*.
Ещё один момент: из-за деления результата qemu_clock_get_ns() пополам, скорее всего логика обработки истёкших таймеров в qemu срабатывает два раза (один раз - вхолостую). Возможно также «замедлились» таймеры qemu, которые не должны были замедляться, например связанные с таймаутами доступа к внешним сетевым ресурсам и т.п.
В общем сейчас это страшный костыль =).
Исходная версия Deleted, :
Говнокостыльный патч для stable-2.1
Сначала я попробовать менять scale, как предложил mix_mix, но это приводило к зависанию при загрузке ядра в гостевой системе. Потом методом тыка я пришёл к этому:
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 7f9a074..31826ca 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -7,6 +7,8 @@
/* timers */
+#define SLOWDOWN 2
+
#define SCALE_MS 1000000
#define SCALE_US 1000
#define SCALE_NS 1
diff --git a/qemu-timer.c b/qemu-timer.c
index 00a5d35..2933473 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -550,13 +550,13 @@ int64_t qemu_clock_get_ns(QEMUClockType type)
switch (type) {
case QEMU_CLOCK_REALTIME:
- return get_clock();
+ return get_clock() / SLOWDOWN;
default:
case QEMU_CLOCK_VIRTUAL:
if (use_icount) {
- return cpu_get_icount();
+ return cpu_get_icount() / SLOWDOWN;
} else {
- return cpu_get_clock();
+ return cpu_get_clock() / SLOWDOWN;
}
case QEMU_CLOCK_HOST:
now = get_clock_realtime();
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index f9fcbca..3ce6499 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -448,13 +448,13 @@ typedef struct model_features_t {
* when KVM is enabled.
*/
static uint32_t kvm_default_features[FEATURE_WORDS] = {
- [FEAT_KVM] = (1 << KVM_FEATURE_CLOCKSOURCE) |
+ [FEAT_KVM] = /*(1 << KVM_FEATURE_CLOCKSOURCE) |*/
(1 << KVM_FEATURE_NOP_IO_DELAY) |
- (1 << KVM_FEATURE_CLOCKSOURCE2) |
+ /*(1 << KVM_FEATURE_CLOCKSOURCE2) |*/
(1 << KVM_FEATURE_ASYNC_PF) |
(1 << KVM_FEATURE_STEAL_TIME) |
- (1 << KVM_FEATURE_PV_EOI) |
- (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT),
+ (1 << KVM_FEATURE_PV_EOI) /*|
+ (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT)*/,
[FEAT_1_ECX] = CPUID_EXT_X2APIC,
};
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index ddedc73..3918cef 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -131,7 +131,7 @@ static const struct kvm_para_features {
int cap;
int feature;
} para_features[] = {
- { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },
+ /*{ KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE },*/
{ KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY },
{ KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP },
{ KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF },
- ping localhost (пакеты отправляются с большей паузой)
- date (время идёт в два раза медленнее =))
- watch -n1
Если не комментировать константы, связанные с KVM, то это работает только в выключенным KVM. Со включенным KVM видимо гостевая система работает с таймерами и прочим как-то в обход qemu.
Обратный отсчёт в isolinux со включенным KVM всегда работает правильно, даже с закомментированными KVM_FEATURE_CLOCKSOURCE*.
Ещё один момент: из-за деления результата qemu_clock_get_ns() пополам, скорее всего логика обработки истёкших таймеров в qemu срабатывает два раза (один раз - вхолостую). Возможно также «замедлились» таймеры qemu, которые не должны были замедляться, например связанные с таймаутами доступа к внешним сетевым ресурсам и т.п.
В общем сейчас это страшный костыль =).