HV: ioapic: unify the access pattern to RTEs

There are two different ways the current implementation adopts to access ioapic
RTEs:

    1. As two 32-bit registers (typically named ''low'' and ''high''), or

    2. As one 64-bit register (typically named ''rte'').

Two issues arise due to the mixed use of these two patterns.

    1. Additional conversions are introduced. As an example, ioapic_get_rte()
       merges two RTE fragments into a uint64_t, while some callers break it
       back to ''low'' and ''high'' again.

    2. It is tricky to choose the proper width of IOAPIC_RTE_xxx constants. SOS
       boot failure is seen when they are 32-bit due to the following code:

           /* reg is uint64_t */
           vioapic->rtbl[pin].reg &= ~IOAPIC_RTE_REM_IRR;

       while making them 64-bit leads to implicit narrowing when the RTEs are accessed
       in the low & high pattern.

This patch defines a union ''ioapic_rte'' and unifies the access pattern
to IOAPIC and vIOAPIC RTEs.

v1 -> v2:

    * Instead of two 32-bit ''low'' and ''high'', define a union that allows
      either 32-bit or 64-bit accesses to RTEs.

Signed-off-by: Junjie Mao <junjie.mao@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
This commit is contained in:
Junjie Mao
2018-07-17 17:49:06 +08:00
committed by lijinxia
parent 9878543356
commit a1069a5117
6 changed files with 209 additions and 213 deletions

View File

@@ -253,6 +253,15 @@ struct ioapic {
uint32_t iowin; PAD3;
};
/* IOAPIC Redirection Table (RTE) Entry structure */
union ioapic_rte {
uint64_t full;
struct {
uint32_t lo_32;
uint32_t hi_32;
} u;
};
#undef PAD4
#undef PAD3
@@ -480,7 +489,9 @@ struct ioapic {
/*
* fields in the IO APIC's redirection table entries
*/
#define IOAPIC_RTE_DEST APIC_ID_MASK /* broadcast addr: all APICs */
#define IOAPIC_RTE_DEST_SHIFT 56U
/* broadcast addr: all APICs */
#define IOAPIC_RTE_DEST_MASK 0xff00000000000000UL
#define IOAPIC_RTE_RESV 0x00fe0000UL /* reserved */

View File

@@ -31,6 +31,9 @@
#ifndef _VIOAPIC_H_
#define _VIOAPIC_H_
#include <apicreg.h>
#include <vm.h>
#define VIOAPIC_BASE 0xFEC00000UL
#define VIOAPIC_SIZE 4096UL
@@ -50,7 +53,7 @@ int vioapic_mmio_read(void *vm, uint64_t gpa,
uint8_t vioapic_pincount(struct vm *vm);
void vioapic_process_eoi(struct vm *vm, uint32_t vector);
bool vioapic_get_rte(struct vm *vm, uint8_t pin, void *rte);
bool vioapic_get_rte(struct vm *vm, uint8_t pin, union ioapic_rte *rte);
int vioapic_mmio_access_handler(struct vcpu *vcpu, struct mem_io *mmio,
void *handler_private_data);

View File

@@ -17,7 +17,6 @@
#define GSI_MASK_IRQ(irq) irq_gsi_mask_unmask((irq), true)
#define GSI_UNMASK_IRQ(irq) irq_gsi_mask_unmask((irq), false)
#define GSI_SET_RTE(irq, rte) ioapic_set_rte((irq), (rte))
void setup_ioapic_irq(void);
@@ -26,8 +25,8 @@ uint32_t irq_gsi_num(void);
uint8_t irq_to_pin(uint32_t irq);
uint32_t pin_to_irq(uint8_t pin);
void irq_gsi_mask_unmask(uint32_t irq, bool mask);
void ioapic_set_rte(uint32_t irq, uint64_t rte);
void ioapic_get_rte(uint32_t irq, uint64_t *rte);
void ioapic_set_rte(uint32_t irq, union ioapic_rte rte);
void ioapic_get_rte(uint32_t irq, union ioapic_rte *rte);
void suspend_ioapic(void);