Skip to content

Commit 2266e13

Browse files
junjiemao1lijinxia
authored andcommitted
lapic: continuous LVT registers as an array
Pointer arithmetic is currently used to calculate the address of a specific Local Vector Table (LVT) register (except LVT_CMCI) in lapic, since the registers are continuously placed with fixed padding in between. However each of these registers are declared as a single uint32_t in struct lapic, resulting pointer arithmetic on a non-array pointer which violates MISRA C requirements. This patch refactors struct lapic by converting the LVT registers fields (again except LVT_CMCI) to an array named lvt. The LVT indices are reordered to reflect the order of the LVT registers on hardware, and reused to index this lvt array. The code before and after the changes is semantically equivalent. Signed-off-by: Junjie Mao <junjie.mao@intel.com> Reviewed-by: Kevin Tian <kevin.tian@intel.com>
1 parent 9a604ed commit 2266e13

File tree

2 files changed

+44
-49
lines changed

2 files changed

+44
-49
lines changed

hypervisor/arch/x86/guest/vlapic.c

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -227,28 +227,28 @@ vlapic_id_write_handler(struct vlapic *vlapic)
227227
static inline bool
228228
vlapic_lvtt_oneshot(struct vlapic *vlapic)
229229
{
230-
return ((vlapic->apic_page->lvt_timer & APIC_LVTT_TM)
230+
return ((vlapic->apic_page->lvt[APIC_LVT_TIMER].val & APIC_LVTT_TM)
231231
== APIC_LVTT_TM_ONE_SHOT);
232232
}
233233

234234
static inline bool
235235
vlapic_lvtt_period(struct vlapic *vlapic)
236236
{
237-
return ((vlapic->apic_page->lvt_timer & APIC_LVTT_TM)
237+
return ((vlapic->apic_page->lvt[APIC_LVT_TIMER].val & APIC_LVTT_TM)
238238
== APIC_LVTT_TM_PERIODIC);
239239
}
240240

241241
static inline bool
242242
vlapic_lvtt_tsc_deadline(struct vlapic *vlapic)
243243
{
244-
return ((vlapic->apic_page->lvt_timer & APIC_LVTT_TM)
244+
return ((vlapic->apic_page->lvt[APIC_LVT_TIMER].val & APIC_LVTT_TM)
245245
== APIC_LVTT_TM_TSCDLT);
246246
}
247247

248248
static inline bool
249249
vlapic_lvtt_masked(struct vlapic *vlapic)
250250
{
251-
return !!(vlapic->apic_page->lvt_timer & APIC_LVTT_M);
251+
return !!(vlapic->apic_page->lvt[APIC_LVT_TIMER].val & APIC_LVTT_M);
252252
}
253253

254254
static void vlapic_create_timer(struct vlapic *vlapic)
@@ -416,28 +416,6 @@ vlapic_set_intr_ready(struct vlapic *vlapic, int vector, bool level)
416416
return 1;
417417
}
418418

419-
static inline uint32_t *
420-
vlapic_get_lvtptr(struct vlapic *vlapic, uint32_t offset)
421-
{
422-
struct lapic *lapic = vlapic->apic_page;
423-
int i;
424-
425-
switch (offset) {
426-
case APIC_OFFSET_CMCI_LVT:
427-
return &lapic->lvt_cmci;
428-
case APIC_OFFSET_TIMER_LVT:
429-
case APIC_OFFSET_THERM_LVT:
430-
case APIC_OFFSET_PERF_LVT:
431-
case APIC_OFFSET_LINT0_LVT:
432-
case APIC_OFFSET_LINT1_LVT:
433-
case APIC_OFFSET_ERROR_LVT:
434-
i = (offset - APIC_OFFSET_TIMER_LVT) >> 2;
435-
return (&lapic->lvt_timer) + i;
436-
default:
437-
panic("vlapic_get_lvt: invalid LVT\n");
438-
}
439-
}
440-
441419
static inline int
442420
lvt_off_to_idx(uint32_t offset)
443421
{
@@ -476,6 +454,28 @@ lvt_off_to_idx(uint32_t offset)
476454
return index;
477455
}
478456

457+
static inline uint32_t *
458+
vlapic_get_lvtptr(struct vlapic *vlapic, uint32_t offset)
459+
{
460+
struct lapic *lapic = vlapic->apic_page;
461+
int i;
462+
463+
switch (offset) {
464+
case APIC_OFFSET_CMCI_LVT:
465+
return &lapic->lvt_cmci;
466+
case APIC_OFFSET_TIMER_LVT:
467+
case APIC_OFFSET_THERM_LVT:
468+
case APIC_OFFSET_PERF_LVT:
469+
case APIC_OFFSET_LINT0_LVT:
470+
case APIC_OFFSET_LINT1_LVT:
471+
case APIC_OFFSET_ERROR_LVT:
472+
i = lvt_off_to_idx(offset);
473+
return &(lapic->lvt[i].val);
474+
default:
475+
panic("vlapic_get_lvt: invalid LVT\n");
476+
}
477+
}
478+
479479
static inline uint32_t
480480
vlapic_get_lvt(struct vlapic *vlapic, uint32_t offset)
481481
{
@@ -557,22 +557,22 @@ vlapic_mask_lvts(struct vlapic *vlapic)
557557
lapic->lvt_cmci |= APIC_LVT_M;
558558
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_CMCI_LVT);
559559

560-
lapic->lvt_timer |= APIC_LVT_M;
560+
lapic->lvt[APIC_LVT_TIMER].val |= APIC_LVT_M;
561561
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_TIMER_LVT);
562562

563-
lapic->lvt_thermal |= APIC_LVT_M;
563+
lapic->lvt[APIC_LVT_THERMAL].val |= APIC_LVT_M;
564564
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_THERM_LVT);
565565

566-
lapic->lvt_pcint |= APIC_LVT_M;
566+
lapic->lvt[APIC_LVT_PMC].val |= APIC_LVT_M;
567567
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_PERF_LVT);
568568

569-
lapic->lvt_lint0 |= APIC_LVT_M;
569+
lapic->lvt[APIC_LVT_LINT0].val |= APIC_LVT_M;
570570
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_LINT0_LVT);
571571

572-
lapic->lvt_lint1 |= APIC_LVT_M;
572+
lapic->lvt[APIC_LVT_LINT1].val |= APIC_LVT_M;
573573
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_LINT1_LVT);
574574

575-
lapic->lvt_error |= APIC_LVT_M;
575+
lapic->lvt[APIC_LVT_ERROR].val |= APIC_LVT_M;
576576
vlapic_lvt_write_handler(vlapic, APIC_OFFSET_ERROR_LVT);
577577
}
578578

@@ -1500,10 +1500,10 @@ void vlapic_restore(struct vlapic *vlapic, struct lapic_regs *regs)
15001500
lapic->tmr[i].val = regs->tmr[i];
15011501
lapic->svr = regs->svr;
15021502
vlapic_svr_write_handler(vlapic);
1503-
lapic->lvt_timer = regs->lvtt;
1504-
lapic->lvt_lint0 = regs->lvt0;
1505-
lapic->lvt_lint1 = regs->lvt1;
1506-
lapic->lvt_error = regs->lvterr;
1503+
lapic->lvt[APIC_LVT_TIMER].val = regs->lvtt;
1504+
lapic->lvt[APIC_LVT_LINT0].val = regs->lvt0;
1505+
lapic->lvt[APIC_LVT_LINT1].val = regs->lvt1;
1506+
lapic->lvt[APIC_LVT_ERROR].val = regs->lvterr;
15071507
lapic->icr_timer = regs->ticr;
15081508
lapic->ccr_timer = regs->tccr;
15091509
lapic->dcr_timer = regs->tdcr;
@@ -1788,7 +1788,7 @@ static int vlapic_timer_expired(void *data)
17881788

17891789
/* inject vcpu timer interrupt if not masked */
17901790
if (!vlapic_lvtt_masked(vlapic))
1791-
vlapic_intr_edge(vcpu, lapic->lvt_timer & APIC_LVTT_VECTOR);
1791+
vlapic_intr_edge(vcpu, lapic->lvt[APIC_LVT_TIMER].val & APIC_LVTT_VECTOR);
17921792

17931793
if (!vlapic_lvtt_period(vlapic))
17941794
vlapic->vlapic_timer.timer.fire_tsc = 0;

hypervisor/include/arch/x86/apicreg.h

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,7 @@ struct lapic {
158158
uint32_t lvt_cmci; PAD3;
159159
uint32_t icr_lo; PAD3;
160160
uint32_t icr_hi; PAD3;
161-
uint32_t lvt_timer; PAD3;
162-
uint32_t lvt_thermal; PAD3;
163-
uint32_t lvt_pcint; PAD3;
164-
uint32_t lvt_lint0; PAD3;
165-
uint32_t lvt_lint1; PAD3;
166-
uint32_t lvt_error; PAD3;
161+
struct lapic_reg lvt[6];
167162
uint32_t icr_timer; PAD3;
168163
uint32_t ccr_timer; PAD3;
169164
/* reserved */ PAD4;
@@ -421,12 +416,12 @@ struct ioapic {
421416
#define APIC_EXTF_IER_CAP 0x00000001
422417

423418
/* LVT table indices */
424-
#define APIC_LVT_LINT0 0
425-
#define APIC_LVT_LINT1 1
426-
#define APIC_LVT_TIMER 2
427-
#define APIC_LVT_ERROR 3
428-
#define APIC_LVT_PMC 4
429-
#define APIC_LVT_THERMAL 5
419+
#define APIC_LVT_TIMER 0
420+
#define APIC_LVT_THERMAL 1
421+
#define APIC_LVT_PMC 2
422+
#define APIC_LVT_LINT0 3
423+
#define APIC_LVT_LINT1 4
424+
#define APIC_LVT_ERROR 5
430425
#define APIC_LVT_CMCI 6
431426
#define APIC_LVT_MAX APIC_LVT_CMCI
432427

0 commit comments

Comments
 (0)