Skip to content

Commit 46bfb03

Browse files
committed
pv_eoi: Verify that feature was enabled
1 parent fac4124 commit 46bfb03

1 file changed

Lines changed: 15 additions & 10 deletions

File tree

src/hw/apic.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <hw/apic_revenant.hpp>
2323
#include <hw/cpu.hpp>
2424
#include <hw/pic.hpp>
25+
#include <kernel/cpuid.hpp>
2526
#include <kernel/irq_manager.hpp>
2627
#include <cstdio>
2728
#include <debug>
@@ -104,7 +105,8 @@ namespace hw {
104105
}
105106

106107
// use KVMs paravirt EOI if supported
107-
//kvm_pv_eoi_init();
108+
if (CPUID::kvm_feature(KVM_FEATURE_PV_EOI))
109+
kvm_pv_eoi_init();
108110

109111
// subscribe to APIC-related interrupts
110112
setup_subs();
@@ -210,14 +212,14 @@ namespace hw {
210212

211213
uint8_t APIC::get_isr()
212214
{
213-
for (uint8_t i = 0; i < 8; i++)
215+
for (int i = 8; i >= 0; i--)
214216
if (lapic.regs->isr[i].reg)
215217
return 32 * i + __builtin_ffs(lapic.regs->isr[i].reg) - 1;
216218
return 255;
217219
}
218220
uint8_t APIC::get_irr()
219221
{
220-
for (uint8_t i = 0; i < 8; i++)
222+
for (int i = 8; i >= 0; i--)
221223
if (lapic.regs->irr[i].reg)
222224
return 32 * i + __builtin_ffs(lapic.regs->irr[i].reg) - 1;
223225
return 255;
@@ -318,7 +320,6 @@ namespace hw {
318320
// http://choon.net/forum/read.php?21,1123399
319321
// https://www.kernel.org/doc/Documentation/virtual/kvm/cpuid.txt
320322

321-
#define KVM_FEATURE_PV_EOI 6
322323
#define KVM_MSR_ENABLED 1
323324
#define MSR_KVM_PV_EOI_EN 0x4b564d04
324325
#define KVM_PV_EOI_BIT 0
@@ -341,7 +342,7 @@ int __test_and_clear_bit(long nr, volatile unsigned long* addr)
341342
static volatile unsigned long kvm_apic_eoi = KVM_PV_EOI_DISABLED;
342343
void kvm_pv_eoi() {
343344

344-
//printf("BEFOR: %#lx intr %u irr %u\n", kvm_apic_eoi, hw::APIC::get_isr(), hw::APIC::get_irr());
345+
printf("BEFOR: %#lx intr %u irr %u\n", kvm_apic_eoi, hw::APIC::get_isr(), hw::APIC::get_irr());
345346
// fast EOI by KVM
346347
if (__test_and_clear_bit(KVM_PV_EOI_BIT, &kvm_apic_eoi)) {
347348
printf("avoided\n");
@@ -350,14 +351,18 @@ void kvm_pv_eoi() {
350351
// fallback to normal APIC EOI
351352
hw::lapic.regs->eoi.reg = 0;
352353
// check after
353-
//printf("AFTER: %#lx intr %u irr %u\n", kvm_apic_eoi, hw::APIC::get_isr(), hw::APIC::get_irr());
354+
printf("AFTER: %#lx intr %u irr %u\n", kvm_apic_eoi, hw::APIC::get_isr(), hw::APIC::get_irr());
354355
}
355356
void kvm_pv_eoi_init() {
357+
printf("* Enabling KVM paravirtual EOI\n");
358+
// set new EOI handler
359+
current_eoi_mechanism = kvm_pv_eoi;
360+
// setup PV EOI using local variable
356361
kvm_apic_eoi = 0;
357362
auto pv_eoi = (uintptr_t) &kvm_apic_eoi;
358-
printf("MSR %#x pv_eoi = %#x\n", MSR_KVM_PV_EOI_EN, pv_eoi);
363+
printf(" MSR %#x pv_eoi = %#x\n", MSR_KVM_PV_EOI_EN, pv_eoi);
359364
hw::CPU::write_msr(MSR_KVM_PV_EOI_EN, pv_eoi | KVM_MSR_ENABLED, 0);
360-
// set new EOI handler
361-
current_eoi_mechanism = kvm_pv_eoi;
362-
kvm_apic_eoi = KVM_PV_EOI_ENABLED;
365+
// verify that the feature was enabled
366+
auto res = hw::CPU::read_msr(MSR_KVM_PV_EOI_EN);
367+
assert(res == (pv_eoi | KVM_MSR_ENABLED));
363368
}

0 commit comments

Comments
 (0)