dm: Skip injecting _PPC and _PCT when _PSS is not constructed

This patch is to eliminate kernel error msgs:
'ACPI Error: AE_NOT_FOUND, Evaluating _PSS'

This is caused by missing of _PSS table in guest ACPI. It would
happen when pstate is not injected to the guest.

Kernel ACPI pstate driver first probes
_PPC(performance capabilites) and _PCT(performance control)
in ACPI. If they exist, then it loads the _PSS(performance state).
If _PPC/_PCT are presented while _PSS is missing, it prints
the error msg.

In acrn-dm, _PPC/_PCT are hard-coded to all vCPUs, while _PSS
are constructed with the pCPUs' pstate data. This is base on
assumption that all VMs can have pstate.

Now the pstate is given to VM only when the VM is not sharing
any CPU(and no RTVM is setup in the scenario).
When the VM doesn't have pstate, the hypercall will return px_cnt=0,
and the _PSS is not constructed. In this case, _PPC/PCT should not
be injected, too.

Tracked-On: #6848

Signed-off-by: Zhou, Wu <wu.zhou@intel.com>
Acked-by: Anthony Xu <anthony.xu@intel.com>
Acked-by: Eddie Dong <eddie.dong@Intel.com>
This commit is contained in:
Zhou, Wu 2021-11-02 16:31:53 +08:00 committed by wenlingz
parent 55249a2f43
commit 1a856f121d

View File

@ -254,7 +254,7 @@ static void dsdt_write_pct(void)
/* _PSS: Performance Supported States
*/
static void dsdt_write_pss(struct vmctx *ctx, int vcpu_id)
static int dsdt_write_pss(struct vmctx *ctx, int vcpu_id)
{
uint8_t vcpu_px_cnt;
int i;
@ -262,12 +262,12 @@ static void dsdt_write_pss(struct vmctx *ctx, int vcpu_id)
vcpu_px_cnt = get_vcpu_px_cnt(ctx, vcpu_id);
if (!vcpu_px_cnt) {
return;
return -1;
}
vcpu_px_data = malloc(vcpu_px_cnt * sizeof(struct acrn_pstate_data));
if (!vcpu_px_data) {
return;
return -1;
}
/* copy and validate px data first */
@ -275,7 +275,7 @@ static void dsdt_write_pss(struct vmctx *ctx, int vcpu_id)
if (get_vcpu_px_data(ctx, vcpu_id, i, vcpu_px_data + i)) {
/* something must be wrong, so skip the write. */
free(vcpu_px_data);
return;
return -1;
}
}
@ -313,11 +313,13 @@ static void dsdt_write_pss(struct vmctx *ctx, int vcpu_id)
free(vcpu_px_data);
return 0;
}
void pm_write_dsdt(struct vmctx *ctx, int ncpu)
{
int i;
int ret;
/* Scope (_PR) */
dsdt_line("");
@ -339,24 +341,27 @@ void pm_write_dsdt(struct vmctx *ctx, int ncpu)
dsdt_line(" {");
dsdt_line("");
dsdt_write_pss(ctx, i);
ret = dsdt_write_pss(ctx, i);
dsdt_write_cst(ctx, i);
/* hard code _PPC and _PCT for all vpu */
if (i == 0) {
dsdt_write_ppc();
dsdt_write_pct();
} else {
dsdt_line(" Method (_PPC, 0, NotSerialized)");
dsdt_line(" {");
dsdt_line(" Return (^^CPU0._PPC)");
dsdt_line(" }");
dsdt_line("");
dsdt_line(" Method (_PCT, 0, NotSerialized)");
dsdt_line(" {");
dsdt_line(" Return (^^CPU0._PCT)");
dsdt_line(" }");
dsdt_line("");
/* if the vm can support px, hv will return the right px/cx cnt.
then hard code _PPC and _PCT for all vpu */
if (ret == 0) {
if (i == 0) {
dsdt_write_ppc();
dsdt_write_pct();
} else {
dsdt_line(" Method (_PPC, 0, NotSerialized)");
dsdt_line(" {");
dsdt_line(" Return (^^CPU0._PPC)");
dsdt_line(" }");
dsdt_line("");
dsdt_line(" Method (_PCT, 0, NotSerialized)");
dsdt_line(" {");
dsdt_line(" Return (^^CPU0._PCT)");
dsdt_line(" }");
dsdt_line("");
}
}
dsdt_line(" }");