Add extended LAPIC state fields to APICCommonState to support AMD's
extended APIC registers:

- efeat: Extended Features register
- ectrl: Extended Control register
- extlvt: Array of extended interrupt LVT registers
- nr_extlvt: Number of extended LVT entries

These fields store the state of AMD's extended APIC registers which
provide additional extended local interrupt vectors beyond the standard
APIC LVT entries.

Add kvm_initialize_extlvt() and kvm_uninitialize_extlvt() to manage
the lifecycle of extended LVT registers. Dynamically allocate and free
the array in APICCommonState based on nr_extlvt supported.

Signed-off-by: Manali Shukla <[email protected]>
---
 hw/i386/kvm/apic.c              | 21 +++++++++++++++++++++
 include/hw/i386/apic_internal.h |  4 ++++
 target/i386/kvm/kvm_i386.h      |  2 ++
 3 files changed, 27 insertions(+)

diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index 9489614bca..7bec7909e9 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -135,6 +135,27 @@ static void kvm_apic_vapic_base_update(APICCommonState *s)
     }
 }
 
+void kvm_initialize_extlvt(X86CPU *cpu, uint32_t nr_extlvt)
+{
+    APICCommonState *s;
+    s = APIC_COMMON(cpu->apic_state);
+
+    s->nr_extlvt = nr_extlvt;
+    s->extlvt = g_malloc0(nr_extlvt * sizeof(uint32_t));
+}
+
+void kvm_uninitialize_extlvt(X86CPU *cpu)
+{
+    APICCommonState *s;
+    s = APIC_COMMON(cpu->apic_state);
+
+    if (s->extlvt) {
+        g_free(s->extlvt);
+        s->extlvt = NULL;
+        s->nr_extlvt = 0;
+    }
+}
+
 static void kvm_apic_put(CPUState *cs, run_on_cpu_data data)
 {
     APICCommonState *s = data.host_ptr;
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index 865b7ed567..e84cbed7f6 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -174,7 +174,11 @@ struct APICCommonState {
     uint32_t lvt[APIC_LVT_NB];
     uint32_t esr; /* error register */
     uint32_t icr[2];
+    uint32_t efeat;
+    uint32_t ectrl;
+    uint32_t *extlvt;
 
+    uint32_t nr_extlvt;
     uint32_t divide_conf;
     int count_shift;
     uint32_t initial_count;
diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h
index 00f8ae0ee4..338433eb52 100644
--- a/target/i386/kvm/kvm_i386.h
+++ b/target/i386/kvm/kvm_i386.h
@@ -73,6 +73,8 @@ struct kvm_cpuid_entry2 *cpuid_find_entry(struct kvm_cpuid2 
*cpuid,
 uint32_t cpuid_entry_get_reg(struct kvm_cpuid_entry2 *entry, int reg);
 uint32_t kvm_x86_build_cpuid(CPUX86State *env, struct kvm_cpuid_entry2 
*entries,
                              uint32_t cpuid_i);
+void kvm_initialize_extlvt(X86CPU *cpu, uint32_t nr_extlvt);
+void kvm_uninitialize_extlvt(X86CPU *cpu);
 #endif /* CONFIG_KVM */
 
 void kvm_pc_setup_irq_routing(bool pci_enabled);
-- 
2.43.0


Reply via email to