uefi: init vlapic according to native lapic

this patch save native lapic configuration and restore it to vm0's vlapic
before its running, then doing hpet timer interrupt injection through vlapic
interface -- this will not mess up vlapic and we can see hpet
timer interrupt coming continuously.

Signed-off-by: Jason Chen CJ <jason.cj.chen@intel.com>
This commit is contained in:
Jason Chen CJ
2018-03-20 03:49:46 +08:00
committed by Jack Ren
parent a87757d602
commit fcb95d02d6
7 changed files with 100 additions and 2 deletions

View File

@@ -1608,6 +1608,31 @@ vlapic_init(struct vlapic *vlapic)
vlapic_reset(vlapic);
}
void vlapic_restore(struct vlapic *vlapic, struct lapic_regs *regs)
{
struct lapic *lapic;
int i;
lapic = vlapic->apic_page;
lapic->tpr = regs->tpr;
lapic->apr = regs->apr;
lapic->ppr = regs->ppr;
lapic->ldr = regs->ldr;
lapic->dfr = regs->dfr;
for (i = 0; i < 8; i++)
lapic->tmr[i].val = regs->tmr[i];
lapic->svr = regs->svr;
vlapic_svr_write_handler(vlapic);
lapic->lvt_timer = regs->lvtt;
lapic->lvt_lint0 = regs->lvt0;
lapic->lvt_lint1 = regs->lvt1;
lapic->lvt_error = regs->lvterr;
lapic->icr_timer = regs->ticr;
lapic->ccr_timer = regs->tccr;
lapic->dcr_timer = regs->tdcr;
}
void
vlapic_cleanup(__unused struct vlapic *vlapic)
{

View File

@@ -266,6 +266,32 @@ int init_lapic(uint32_t cpu_id)
return 0;
}
void save_lapic(struct lapic_regs *regs)
{
regs->id = read_lapic_reg32(LAPIC_ID_REGISTER);
regs->tpr = read_lapic_reg32(LAPIC_TASK_PRIORITY_REGISTER);
regs->apr = read_lapic_reg32(LAPIC_ARBITRATION_PRIORITY_REGISTER);
regs->ppr = read_lapic_reg32(LAPIC_PROCESSOR_PRIORITY_REGISTER);
regs->ldr = read_lapic_reg32(LAPIC_LOGICAL_DESTINATION_REGISTER);
regs->dfr = read_lapic_reg32(LAPIC_DESTINATION_FORMAT_REGISTER);
regs->tmr[0] = read_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_0);
regs->tmr[1] = read_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_1);
regs->tmr[2] = read_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_2);
regs->tmr[3] = read_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_3);
regs->tmr[4] = read_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_4);
regs->tmr[5] = read_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_5);
regs->tmr[6] = read_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_6);
regs->tmr[7] = read_lapic_reg32(LAPIC_TRIGGER_MODE_REGISTER_7);
regs->svr = read_lapic_reg32(LAPIC_SPURIOUS_VECTOR_REGISTER);
regs->lvtt = read_lapic_reg32(LAPIC_LVT_TIMER_REGISTER);
regs->lvt0 = read_lapic_reg32(LAPIC_LVT_LINT0_REGISTER);
regs->lvt1 = read_lapic_reg32(LAPIC_LVT_LINT1_REGISTER);
regs->lvterr = read_lapic_reg32(LAPIC_LVT_ERROR_REGISTER);
regs->ticr = read_lapic_reg32(LAPIC_INITIAL_COUNT_REGISTER);
regs->tccr = read_lapic_reg32(LAPIC_CURRENT_COUNT_REGISTER);
regs->tdcr = read_lapic_reg32(LAPIC_DIVIDE_CONFIGURATION_REGISTER);
}
int send_lapic_eoi(void)
{
write_lapic_reg32(LAPIC_EOI_REGISTER, 0);

View File

@@ -51,7 +51,9 @@ int interrupt_init(uint32_t cpu_id)
if (status != 0)
return -ENODEV;
#ifndef CONFIG_EFI_STUB
CPU_IRQ_ENABLE();
#endif
return status;
}

View File

@@ -1282,9 +1282,10 @@ static void override_uefi_vmcs(struct vcpu *vcpu)
/* Interrupt */
field = VMX_GUEST_RFLAGS;
cur_context->rflags = 0x2;
cur_context->rflags |= 1 << 9; /* enable intr for efi stub */
/* clear flags for CF/PF/AF/ZF/SF/OF */
cur_context->rflags = efi_ctx->rflags & ~(0x8d5);
exec_vmwrite(field, cur_context->rflags);
pr_dbg("VMX_GUEST_RFLAGS: 0x%016llx ", cur_context->rflags);
}
#endif