Commit 678e12cc9054e8a9eafc43a5b4b65d335d6651d4

Authored by Gleb Natapov
Committed by Anthony Liguori
1 parent c4f31a0a

Don't use cpu_index as apic_id.

(patch is on top of "Apic creation should not depend on pci" series)

Currently cpu_index is used as cpu apic id on x86.  This is incorrect
since apic ids not have to be continuous (they can also encode cpu
hierarchy information). This patch uses cpuid_apic_id for initial apic id
value. For now cpuid_apic_id is set to be equal to cpu_index so behaviour
is fully backward compatible, but it allows us to add qemu option to
provide other values for cpu apic id.

Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing 3 changed files with 40 additions and 13 deletions
hw/apic.c
@@ -83,12 +83,13 @@ typedef struct APICState { @@ -83,12 +83,13 @@ typedef struct APICState {
83 int count_shift; 83 int count_shift;
84 uint32_t initial_count; 84 uint32_t initial_count;
85 int64_t initial_count_load_time, next_time; 85 int64_t initial_count_load_time, next_time;
  86 + uint32_t idx;
86 QEMUTimer *timer; 87 QEMUTimer *timer;
87 } APICState; 88 } APICState;
88 89
89 static int apic_io_memory; 90 static int apic_io_memory;
90 static APICState *local_apics[MAX_APICS + 1]; 91 static APICState *local_apics[MAX_APICS + 1];
91 -static int last_apic_id = 0; 92 +static int last_apic_idx = 0;
92 static int apic_irq_delivered; 93 static int apic_irq_delivered;
93 94
94 95
@@ -400,6 +401,23 @@ static void apic_eoi(APICState *s) @@ -400,6 +401,23 @@ static void apic_eoi(APICState *s)
400 apic_update_irq(s); 401 apic_update_irq(s);
401 } 402 }
402 403
  404 +static int apic_find_dest(uint8_t dest)
  405 +{
  406 + APICState *apic = local_apics[dest];
  407 + int i;
  408 +
  409 + if (apic && apic->id == dest)
  410 + return dest; /* shortcut in case apic->id == apic->idx */
  411 +
  412 + for (i = 0; i < MAX_APICS; i++) {
  413 + apic = local_apics[i];
  414 + if (apic && apic->id == dest)
  415 + return i;
  416 + }
  417 +
  418 + return -1;
  419 +}
  420 +
403 static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask, 421 static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
404 uint8_t dest, uint8_t dest_mode) 422 uint8_t dest, uint8_t dest_mode)
405 { 423 {
@@ -410,8 +428,10 @@ static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask, @@ -410,8 +428,10 @@ static void apic_get_delivery_bitmask(uint32_t *deliver_bitmask,
410 if (dest == 0xff) { 428 if (dest == 0xff) {
411 memset(deliver_bitmask, 0xff, MAX_APIC_WORDS * sizeof(uint32_t)); 429 memset(deliver_bitmask, 0xff, MAX_APIC_WORDS * sizeof(uint32_t));
412 } else { 430 } else {
  431 + int idx = apic_find_dest(dest);
413 memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t)); 432 memset(deliver_bitmask, 0x00, MAX_APIC_WORDS * sizeof(uint32_t));
414 - set_bit(deliver_bitmask, dest); 433 + if (idx >= 0)
  434 + set_bit(deliver_bitmask, idx);
415 } 435 }
416 } else { 436 } else {
417 /* XXX: cluster mode */ 437 /* XXX: cluster mode */
@@ -457,8 +477,7 @@ static void apic_init_ipi(APICState *s) @@ -457,8 +477,7 @@ static void apic_init_ipi(APICState *s)
457 477
458 cpu_reset(s->cpu_env); 478 cpu_reset(s->cpu_env);
459 479
460 - if (!(s->apicbase & MSR_IA32_APICBASE_BSP))  
461 - s->cpu_env->halted = 1; 480 + s->cpu_env->halted = !(s->apicbase & MSR_IA32_APICBASE_BSP);
462 } 481 }
463 482
464 /* send a SIPI message to the CPU to start it */ 483 /* send a SIPI message to the CPU to start it */
@@ -487,14 +506,14 @@ static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode, @@ -487,14 +506,14 @@ static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode,
487 break; 506 break;
488 case 1: 507 case 1:
489 memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask)); 508 memset(deliver_bitmask, 0x00, sizeof(deliver_bitmask));
490 - set_bit(deliver_bitmask, s->id); 509 + set_bit(deliver_bitmask, s->idx);
491 break; 510 break;
492 case 2: 511 case 2:
493 memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask)); 512 memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
494 break; 513 break;
495 case 3: 514 case 3:
496 memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask)); 515 memset(deliver_bitmask, 0xff, sizeof(deliver_bitmask));
497 - reset_bit(deliver_bitmask, s->id); 516 + reset_bit(deliver_bitmask, s->idx);
498 break; 517 break;
499 } 518 }
500 519
@@ -870,13 +889,14 @@ static int apic_load(QEMUFile *f, void *opaque, int version_id) @@ -870,13 +889,14 @@ static int apic_load(QEMUFile *f, void *opaque, int version_id)
870 static void apic_reset(void *opaque) 889 static void apic_reset(void *opaque)
871 { 890 {
872 APICState *s = opaque; 891 APICState *s = opaque;
  892 + int bsp = cpu_is_bsp(s->cpu_env);
873 893
874 s->apicbase = 0xfee00000 | 894 s->apicbase = 0xfee00000 |
875 - (s->id ? 0 : MSR_IA32_APICBASE_BSP) | MSR_IA32_APICBASE_ENABLE; 895 + (bsp ? MSR_IA32_APICBASE_BSP : 0) | MSR_IA32_APICBASE_ENABLE;
876 896
877 apic_init_ipi(s); 897 apic_init_ipi(s);
878 898
879 - if (s->id == 0) { 899 + if (bsp) {
880 /* 900 /*
881 * LINT0 delivery mode on CPU #0 is set to ExtInt at initialization 901 * LINT0 delivery mode on CPU #0 is set to ExtInt at initialization
882 * time typically by BIOS, so PIC interrupt can be delivered to the 902 * time typically by BIOS, so PIC interrupt can be delivered to the
@@ -902,12 +922,12 @@ int apic_init(CPUState *env) @@ -902,12 +922,12 @@ int apic_init(CPUState *env)
902 { 922 {
903 APICState *s; 923 APICState *s;
904 924
905 - if (last_apic_id >= MAX_APICS) 925 + if (last_apic_idx >= MAX_APICS)
906 return -1; 926 return -1;
907 s = qemu_mallocz(sizeof(APICState)); 927 s = qemu_mallocz(sizeof(APICState));
908 env->apic_state = s; 928 env->apic_state = s;
909 - s->id = last_apic_id++;  
910 - env->cpuid_apic_id = s->id; 929 + s->idx = last_apic_idx++;
  930 + s->id = env->cpuid_apic_id;
911 s->cpu_env = env; 931 s->cpu_env = env;
912 932
913 apic_reset(s); 933 apic_reset(s);
@@ -923,10 +943,10 @@ int apic_init(CPUState *env) @@ -923,10 +943,10 @@ int apic_init(CPUState *env)
923 } 943 }
924 s->timer = qemu_new_timer(vm_clock, apic_timer, s); 944 s->timer = qemu_new_timer(vm_clock, apic_timer, s);
925 945
926 - register_savevm("apic", s->id, 2, apic_save, apic_load, s); 946 + register_savevm("apic", s->idx, 2, apic_save, apic_load, s);
927 qemu_register_reset(apic_reset, 0, s); 947 qemu_register_reset(apic_reset, 0, s);
928 948
929 - local_apics[s->id] = s; 949 + local_apics[s->idx] = s;
930 return 0; 950 return 0;
931 } 951 }
932 952
@@ -830,6 +830,11 @@ static int load_option_rom(const char *oprom, target_phys_addr_t start, @@ -830,6 +830,11 @@ static int load_option_rom(const char *oprom, target_phys_addr_t start,
830 return size; 830 return size;
831 } 831 }
832 832
  833 +int cpu_is_bsp(CPUState *env)
  834 +{
  835 + return env->cpuid_apic_id == 0;
  836 +}
  837 +
833 /* PC hardware initialisation */ 838 /* PC hardware initialisation */
834 static void pc_init1(ram_addr_t ram_size, 839 static void pc_init1(ram_addr_t ram_size,
835 const char *boot_device, 840 const char *boot_device,
@@ -877,6 +882,7 @@ static void pc_init1(ram_addr_t ram_size, @@ -877,6 +882,7 @@ static void pc_init1(ram_addr_t ram_size,
877 exit(1); 882 exit(1);
878 } 883 }
879 if ((env->cpuid_features & CPUID_APIC) || smp_cpus > 1) { 884 if ((env->cpuid_features & CPUID_APIC) || smp_cpus > 1) {
  885 + env->cpuid_apic_id = env->cpu_index;
880 apic_init(env); 886 apic_init(env);
881 } 887 }
882 qemu_register_reset(main_cpu_reset, 0, env); 888 qemu_register_reset(main_cpu_reset, 0, env);
@@ -162,4 +162,5 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn, @@ -162,4 +162,5 @@ void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
162 162
163 void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd); 163 void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd);
164 164
  165 +int cpu_is_bsp(CPUState *env);
165 #endif 166 #endif