lapic = (struct acpi_20_madt_lapic *)(io_apic + 1);
madt_lapic0_addr = (uint32_t)lapic;
- for ( i = 0; i < MAX_VCPUS; i++ )
+ for ( i = 0; i < HVM_MAX_VCPUS; i++ )
{
memset(lapic, 0, sizeof(*lapic));
lapic->type = ACPI_PROCESSOR_LOCAL_APIC;
/* Processor ID must match processor-object IDs in the DSDT. */
lapic->acpi_processor_id = i;
lapic->apic_id = LAPIC_ID(i);
- lapic->flags = (i < hvm_info->nr_vcpus) ? ACPI_LOCAL_APIC_ENABLED : 0;
+ lapic->flags = ((i < hvm_info->nr_vcpus) &&
+ test_bit(i, hvm_info->vcpu_online)
+ ? ACPI_LOCAL_APIC_ENABLED : 0);
offset += sizeof(*lapic);
lapic++;
}
#define XEN_PF_IOBASE 0x10
#define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
-/* Maximum we can support with current vLAPIC ID mapping. */
-#define MAX_VCPUS 128
-
/* Located at BIOS_INFO_PHYSICAL_ADDRESS. */
struct bios_info {
uint8_t com1_present:1; /* 0[0] - System has COM1? */
#define BUG_ON(p) do { if (p) BUG(); } while (0)
#define BUILD_BUG_ON(p) ((void)sizeof(char[1 - 2 * !!(p)]))
+static inline int test_bit(unsigned int b, void *p)
+{
+ return !!(((uint8_t *)p)[b>>3] & (1u<<(b&7)));
+}
+
/* MSR access */
void wrmsr(uint32_t idx, uint64_t v);
uint64_t rdmsr(uint32_t idx);
#endif
char *image;
int memsize, target=-1, vcpus = 1, acpi = 0, apic = 1;
+ uint64_t vcpu_avail = 1;
static char *kwd_list[] = { "domid",
- "memsize", "image", "target", "vcpus", "acpi",
- "apic", NULL };
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiii", kwd_list,
+ "memsize", "image", "target", "vcpus",
+ "vcpu_avail", "acpi", "apic", NULL };
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iilii", kwd_list,
&dom, &memsize, &image, &target, &vcpus,
- &acpi, &apic) )
+ &vcpu_avail, &acpi, &apic) )
return NULL;
if ( target == -1 )
va_hvm->acpi_enabled = acpi;
va_hvm->apic_mode = apic;
va_hvm->nr_vcpus = vcpus;
+ ((uint64_t *)va_hvm->vcpu_online)[0] = vcpu_avail;
+ ((uint64_t *)va_hvm->vcpu_online)[1] = 0;
for ( i = 0, sum = 0; i < va_hvm->length; i++ )
sum += ((uint8_t *)va_hvm)[i];
va_hvm->checksum -= sum;
" dom [int]: Identifier of domain to build into.\n"
" image [str]: Name of HVM loader image file.\n"
" vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n"
+ " vcpu_avail [long, 1]: Which Virtual CPUS available.\n\n"
"Returns: [int] 0 on success; -1 on error.\n" },
{ "hvm_get_param",
log.debug("memsize = %d", memmax_mb)
log.debug("target = %d", mem_mb)
log.debug("vcpus = %d", self.vm.getVCpuCount())
+ log.debug("vcpu_avail = %li", self.vm.getVCpuAvail())
log.debug("acpi = %d", self.acpi)
log.debug("apic = %d", self.apic)
memsize = memmax_mb,
target = mem_mb,
vcpus = self.vm.getVCpuCount(),
+ vcpu_avail = self.vm.getVCpuAvail(),
acpi = self.acpi,
apic = self.apic)
rc['notes'] = { 'SUSPEND_CANCEL': 1 }
#define HVM_INFO_OFFSET 0x800
#define HVM_INFO_PADDR ((HVM_INFO_PFN << 12) + HVM_INFO_OFFSET)
+/* Maximum we can support with current vLAPIC ID mapping. */
+#define HVM_MAX_VCPUS 128
+
struct hvm_info_table {
char signature[8]; /* "HVM INFO" */
uint32_t length;
* RAM above 4GB
*/
uint32_t high_mem_pgend;
+
+ /* Bitmap of which CPUs are online at boot time. */
+ uint8_t vcpu_online[HVM_MAX_VCPUS/8];
};
#endif /* __XEN_PUBLIC_HVM_HVM_INFO_TABLE_H__ */