mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 09:13:55 -06:00
apic, i386/tcg: add x2apic transitions
This commit adds support for x2APIC transitions when writing to MSR_IA32_APICBASE register and finally adds CPUID_EXT_X2APIC to TCG_EXT_FEATURES. The set_base in APICCommonClass now returns an integer to indicate error in execution. apic_set_base return -1 on invalid APIC state transition, accelerator can use this to raise appropriate exception. Signed-off-by: Bui Quang Minh <minhquangbui99@gmail.com> Message-Id: <20240111154404.5333-4-minhquangbui99@gmail.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
b5ee0468e9
commit
774204cf98
10 changed files with 96 additions and 19 deletions
|
@ -308,8 +308,49 @@ bool is_x2apic_mode(DeviceState *dev)
|
|||
return s->apicbase & MSR_IA32_APICBASE_EXTD;
|
||||
}
|
||||
|
||||
static void apic_set_base(APICCommonState *s, uint64_t val)
|
||||
static int apic_set_base_check(APICCommonState *s, uint64_t val)
|
||||
{
|
||||
/* Enable x2apic when x2apic is not supported by CPU */
|
||||
if (!cpu_has_x2apic_feature(&s->cpu->env) &&
|
||||
val & MSR_IA32_APICBASE_EXTD) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transition into invalid state
|
||||
* (s->apicbase & MSR_IA32_APICBASE_ENABLE == 0) &&
|
||||
* (s->apicbase & MSR_IA32_APICBASE_EXTD) == 1
|
||||
*/
|
||||
if (!(val & MSR_IA32_APICBASE_ENABLE) &&
|
||||
(val & MSR_IA32_APICBASE_EXTD)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Invalid transition from disabled mode to x2APIC */
|
||||
if (!(s->apicbase & MSR_IA32_APICBASE_ENABLE) &&
|
||||
!(s->apicbase & MSR_IA32_APICBASE_EXTD) &&
|
||||
(val & MSR_IA32_APICBASE_ENABLE) &&
|
||||
(val & MSR_IA32_APICBASE_EXTD)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Invalid transition from x2APIC to xAPIC */
|
||||
if ((s->apicbase & MSR_IA32_APICBASE_ENABLE) &&
|
||||
(s->apicbase & MSR_IA32_APICBASE_EXTD) &&
|
||||
(val & MSR_IA32_APICBASE_ENABLE) &&
|
||||
!(val & MSR_IA32_APICBASE_EXTD)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int apic_set_base(APICCommonState *s, uint64_t val)
|
||||
{
|
||||
if (apic_set_base_check(s, val) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
s->apicbase = (val & 0xfffff000) |
|
||||
(s->apicbase & (MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE));
|
||||
/* if disabled, cannot be enabled again */
|
||||
|
@ -318,6 +359,25 @@ static void apic_set_base(APICCommonState *s, uint64_t val)
|
|||
cpu_clear_apic_feature(&s->cpu->env);
|
||||
s->spurious_vec &= ~APIC_SV_ENABLE;
|
||||
}
|
||||
|
||||
/* Transition from disabled mode to xAPIC */
|
||||
if (!(s->apicbase & MSR_IA32_APICBASE_ENABLE) &&
|
||||
(val & MSR_IA32_APICBASE_ENABLE)) {
|
||||
s->apicbase |= MSR_IA32_APICBASE_ENABLE;
|
||||
cpu_set_apic_feature(&s->cpu->env);
|
||||
}
|
||||
|
||||
/* Transition from xAPIC to x2APIC */
|
||||
if (cpu_has_x2apic_feature(&s->cpu->env) &&
|
||||
!(s->apicbase & MSR_IA32_APICBASE_EXTD) &&
|
||||
(val & MSR_IA32_APICBASE_EXTD)) {
|
||||
s->apicbase |= MSR_IA32_APICBASE_EXTD;
|
||||
|
||||
s->log_dest = ((s->initial_apic_id & 0xffff0) << 16) |
|
||||
(1 << (s->initial_apic_id & 0xf));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void apic_set_tpr(APICCommonState *s, uint8_t val)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue