mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
devices: ioapic: Always retrieve destination field on 8 bits
When the destination mode is physical, the destination field should only be defined through bits 56-59, as defined in the IOAPIC spec. But from the APIC specification, the APIC ID is always defined on 8 bits no matter which destination mode is selected. That's why we always retrieve the destination field based on bits 56-63. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
committed by
Rob Bradford
parent
a8c2d70869
commit
9dffc5da5c
@@ -7,8 +7,6 @@ use std::result;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Invalid destination mode.
|
|
||||||
InvalidDestinationMode,
|
|
||||||
/// Invalid trigger mode.
|
/// Invalid trigger mode.
|
||||||
InvalidTriggerMode,
|
InvalidTriggerMode,
|
||||||
/// Invalid delivery mode.
|
/// Invalid delivery mode.
|
||||||
|
|||||||
@@ -67,10 +67,12 @@ fn trigger_mode(entry: RedirectionTableEntry) -> u8 {
|
|||||||
fn interrupt_mask(entry: RedirectionTableEntry) -> u8 {
|
fn interrupt_mask(entry: RedirectionTableEntry) -> u8 {
|
||||||
((entry >> 16) & 0x1u64) as u8
|
((entry >> 16) & 0x1u64) as u8
|
||||||
}
|
}
|
||||||
fn destination_field_physical(entry: RedirectionTableEntry) -> u8 {
|
fn destination_field(entry: RedirectionTableEntry) -> u8 {
|
||||||
((entry >> 56) & 0xfu64) as u8
|
// When the destination mode is physical, the destination field should only
|
||||||
}
|
// be defined through bits 56-59, as defined in the IOAPIC specification.
|
||||||
fn destination_field_logical(entry: RedirectionTableEntry) -> u8 {
|
// But from the APIC specification, the APIC ID is always defined on 8 bits
|
||||||
|
// no matter which destination mode is selected. That's why we always
|
||||||
|
// retrieve the destination field based on bits 56-63.
|
||||||
((entry >> 56) & 0xffu64) as u8
|
((entry >> 56) & 0xffu64) as u8
|
||||||
}
|
}
|
||||||
fn set_delivery_status(entry: &mut RedirectionTableEntry, val: u8) {
|
fn set_delivery_status(entry: &mut RedirectionTableEntry, val: u8) {
|
||||||
@@ -100,12 +102,6 @@ const IOWIN_OFF: u8 = 0x10;
|
|||||||
const IOWIN_SCALE: u8 = 0x2;
|
const IOWIN_SCALE: u8 = 0x2;
|
||||||
const REG_MAX_OFFSET: u8 = IOWIN_OFF + (NUM_IOAPIC_PINS as u8 * 2) - 1;
|
const REG_MAX_OFFSET: u8 = IOWIN_OFF + (NUM_IOAPIC_PINS as u8 * 2) - 1;
|
||||||
|
|
||||||
#[repr(u8)]
|
|
||||||
enum DestinationMode {
|
|
||||||
Physical = 0,
|
|
||||||
Logical = 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
enum TriggerMode {
|
enum TriggerMode {
|
||||||
Edge = 0,
|
Edge = 0,
|
||||||
@@ -294,11 +290,7 @@ impl Ioapic {
|
|||||||
|
|
||||||
// Validate Destination Mode value, and retrieve Destination ID
|
// Validate Destination Mode value, and retrieve Destination ID
|
||||||
let destination_mode = destination_mode(entry);
|
let destination_mode = destination_mode(entry);
|
||||||
let destination_id: u8 = match destination_mode {
|
let destination_id = destination_field(entry);
|
||||||
x if x == DestinationMode::Physical as u8 => destination_field_physical(entry),
|
|
||||||
x if x == DestinationMode::Logical as u8 => destination_field_logical(entry),
|
|
||||||
_ => return Err(Error::InvalidDestinationMode),
|
|
||||||
};
|
|
||||||
|
|
||||||
// When this bit is set, the message is directed to the processor with
|
// When this bit is set, the message is directed to the processor with
|
||||||
// the lowest interrupt priority among processors that can receive the
|
// the lowest interrupt priority among processors that can receive the
|
||||||
|
|||||||
Reference in New Issue
Block a user