UCHAR ProcessorID;
NTSTATUS Status;
KEVENT Event;
+ vcpu_info_t *Vcpu;
+ PBOOLEAN Registered;
} SYSTEM_PROCESSOR, *PSYSTEM_PROCESSOR;
typedef struct _SYSTEM_WATCHDOG {
return status;
}
-static NTSTATUS
-SystemProcessorRegisterVcpuInfo(
- IN ULONG Cpu
+XEN_API
+NTSTATUS
+SystemProcessorVcpuInfo(
+ IN ULONG Cpu,
+ OUT vcpu_info_t **Vcpu
)
{
PSYSTEM_CONTEXT Context = &SystemContext;
- unsigned int vcpu_id;
- PHYSICAL_ADDRESS Address;
- PFN_NUMBER Pfn;
- ULONG Offset;
+ PSYSTEM_PROCESSOR Processor = &Context->Processor[Cpu];
NTSTATUS status;
- status = SystemProcessorVcpuId(Cpu, &vcpu_id);
- ASSERT(NT_SUCCESS(status));
-
- Offset = sizeof (vcpu_info_t) * Cpu;
-
- Pfn = MmGetMdlPfnArray(Context->Mdl)[Offset >> PAGE_SHIFT];
- Offset = Offset & (PAGE_SIZE - 1);
-
- status = VcpuRegisterVcpuInfo(vcpu_id, Pfn, Offset);
- if (!NT_SUCCESS(status))
+ status = STATUS_UNSUCCESSFUL;
+ if (Cpu >= __SystemProcessorCount())
goto fail1;
- Address.QuadPart = (ULONGLONG)Pfn << PAGE_SHIFT;
- Address.QuadPart += Offset;
-
- Info("vcpu_info @ %08x.%08x\n", Address.HighPart, Address.LowPart);
+ ASSERT(*Processor->Registered);
+ *Vcpu = Processor->Vcpu;
return STATUS_SUCCESS;
fail1:
- Error("fail1 (%08x)\n", status);
-
return status;
}
XEN_API
NTSTATUS
-SystemProcessorVcpuInfo(
- IN ULONG Cpu,
- OUT vcpu_info_t **vcpu_info
+SystemProcessorRegisterVcpuInfo(
+ IN ULONG Cpu,
+ IN BOOLEAN Force
)
{
- PSYSTEM_CONTEXT Context = &SystemContext;
- PMDL Mdl = Context->Mdl;
- NTSTATUS status;
+ PSYSTEM_CONTEXT Context = &SystemContext;
+ PSYSTEM_PROCESSOR Processor = &Context->Processor[Cpu];
+ PMDL Mdl = Context->Mdl;
+ ULONG Offset;
+ PFN_NUMBER Pfn;
+ PHYSICAL_ADDRESS Address;
+ PUCHAR MdlMappedSystemVa;
+ NTSTATUS status;
status = STATUS_UNSUCCESSFUL;
if (Cpu >= __SystemProcessorCount())
goto fail1;
ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
- *vcpu_info = Mdl->MappedSystemVa;
- *vcpu_info += Cpu;
+ MdlMappedSystemVa = Mdl->MappedSystemVa;
+
+ Offset = sizeof (vcpu_info_t) * HVM_MAX_VCPUS;
+ Offset += sizeof (BOOLEAN) * Cpu;
+
+ Processor->Registered = (PBOOLEAN)(MdlMappedSystemVa + Offset);
+ Offset = sizeof (vcpu_info_t) * Cpu;
+
+ Processor->Vcpu = (vcpu_info_t *)(MdlMappedSystemVa + Offset);
+
+ Pfn = MmGetMdlPfnArray(Context->Mdl)[Offset >> PAGE_SHIFT];
+ Offset = Offset & (PAGE_SIZE - 1);
+
+ if (!*Processor->Registered || Force) {
+ unsigned int vcpu_id;
+
+ status = SystemProcessorVcpuId(Cpu, &vcpu_id);
+ ASSERT(NT_SUCCESS(status));
+
+ status = VcpuRegisterVcpuInfo(vcpu_id, Pfn, Offset);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ LogPrintf(LOG_LEVEL_INFO,
+ "XEN: REGISTER vcpu_info[%u]\n",
+ Cpu);
+
+ *Processor->Registered = TRUE;
+ }
+
+ Address.QuadPart = (ULONGLONG)Pfn << PAGE_SHIFT;
+ Address.QuadPart += Offset;
+
+ LogPrintf(LOG_LEVEL_INFO,
+ "XEN: vcpu_info[%u] @ %08x.%08x\n",
+ Cpu,
+ Address.HighPart,
+ Address.LowPart);
+
return STATUS_SUCCESS;
+fail2:
+ Error("fail2\n");
+
+ Processor->Vcpu = NULL;
+ Processor->Registered = NULL;
+
fail1:
+ Error("fail1 (%08x)\n", status);
+
return status;
}
SystemProcessorInformation(Cpu);
- status = SystemProcessorRegisterVcpuInfo(Cpu);
+ status = SystemProcessorRegisterVcpuInfo(Cpu, FALSE);
if (!NT_SUCCESS(status))
goto fail1;
NTSTATUS status;
Size = sizeof (vcpu_info_t) * HVM_MAX_VCPUS;
+ Size += sizeof (BOOLEAN) * HVM_MAX_VCPUS;
Size = P2ROUNDUP(Size, PAGE_SIZE);
Context->Mdl = DriverGetNamedPages("VCPU_INFO", Size >> PAGE_SHIFT);