1 // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 // SPDX-License-Identifier: Apache-2.0
3 //
4 // Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
5 // Use of this source code is governed by a BSD-style license that can be
6 // found in the LICENSE-BSD-3-Clause file.
7
8 use std::result;
9 use std::sync::Arc;
10
11 pub type Result<T> = result::Result<T, hypervisor::HypervisorCpuError>;
12
13 // Defines poached from apicdef.h kernel header.
14 pub const APIC_LVT0: usize = 0x350;
15 pub const APIC_LVT1: usize = 0x360;
16 pub const APIC_MODE_NMI: u32 = 0x4;
17 pub const APIC_MODE_EXTINT: u32 = 0x7;
18
set_apic_delivery_mode(reg: u32, mode: u32) -> u3219 pub fn set_apic_delivery_mode(reg: u32, mode: u32) -> u32 {
20 ((reg) & !0x700) | ((mode) << 8)
21 }
22
23 /// Configures LAPICs. LAPIC0 is set for external interrupts, LAPIC1 is set for NMI.
24 ///
25 /// # Arguments
26 /// * `vcpu` - The VCPU object to configure.
set_lint(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()>27 pub fn set_lint(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
28 let mut klapic = vcpu.get_lapic()?;
29
30 let lvt_lint0 = klapic.get_klapic_reg(APIC_LVT0);
31 klapic.set_klapic_reg(
32 APIC_LVT0,
33 set_apic_delivery_mode(lvt_lint0, APIC_MODE_EXTINT),
34 );
35 let lvt_lint1 = klapic.get_klapic_reg(APIC_LVT1);
36 klapic.set_klapic_reg(APIC_LVT1, set_apic_delivery_mode(lvt_lint1, APIC_MODE_NMI));
37
38 vcpu.set_lapic(&klapic)
39 }
40