dm: add _CPC to guest ACPI pm tables
The optional object _CPC declares an interface that allows OSPM to transition the processor into a performance state based on a continuous range of allowable values. It is associated with HWP on intel CPUs. Although Linux intel_pstate driver can have its performance managing abilities without _CPC, it may still need this _CPC table to implement some features such as providing the kernel multi-core scheduler with core priority info. As currently we are giving guests a vHWP interface for the multi-core scheduler, this patch adds _CPC to the guest ACPI. _CPC is written only when the hypervisor decides the guest should have vHWP, using the existing pm hypercall ACRN_PMCMD_GET_PX_CNT. The idea is: - If the VM supports vHWP, then the guest is having continuous p-state. Thus it doesn't have a specific px_cnt. The hypercall returns success and px_cnt = 0. - If the VM's p-state is hidden or hv doesn't have its p-state info, the hypercall returns fail. Tracked-On: #8414 Signed-off-by: Wu Zhou <wu.zhou@intel.com> Reviewed-by: Jian Jun Chen <jian.jun.chen@intel.com>
This commit is contained in:
parent
c5d019b836
commit
8c38cd5734
|
@ -22,15 +22,15 @@ static inline int get_vcpu_pm_info(struct vmctx *ctx, int vcpu_id,
|
|||
return vm_get_cpu_state(ctx, pm_info);
|
||||
}
|
||||
|
||||
static inline uint8_t get_vcpu_px_cnt(struct vmctx *ctx, int vcpu_id)
|
||||
static inline int get_vcpu_px_cnt(struct vmctx *ctx, int vcpu_id, uint8_t *px_cnt)
|
||||
{
|
||||
uint64_t px_cnt;
|
||||
uint64_t px_cnt_u64;
|
||||
int ret;
|
||||
|
||||
if (get_vcpu_pm_info(ctx, vcpu_id, ACRN_PMCMD_GET_PX_CNT, &px_cnt)) {
|
||||
return 0;
|
||||
}
|
||||
ret = get_vcpu_pm_info(ctx, vcpu_id, ACRN_PMCMD_GET_PX_CNT, &px_cnt_u64);
|
||||
*px_cnt = (uint8_t)px_cnt_u64;
|
||||
|
||||
return (uint8_t)px_cnt;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint8_t get_vcpu_cx_cnt(struct vmctx *ctx, int vcpu_id)
|
||||
|
@ -259,9 +259,13 @@ static int dsdt_write_pss(struct vmctx *ctx, int vcpu_id)
|
|||
uint8_t vcpu_px_cnt;
|
||||
int i;
|
||||
struct acrn_pstate_data *vcpu_px_data;
|
||||
int ret;
|
||||
|
||||
vcpu_px_cnt = get_vcpu_px_cnt(ctx, vcpu_id);
|
||||
if (!vcpu_px_cnt) {
|
||||
ret = get_vcpu_px_cnt(ctx, vcpu_id, &vcpu_px_cnt);
|
||||
/* vcpu_px_cnt = 0 Indicates vcpu supports continuous pstate.
|
||||
* Then we should write _CPC instate of _PSS
|
||||
*/
|
||||
if (ret || !vcpu_px_cnt) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -316,10 +320,49 @@ static int dsdt_write_pss(struct vmctx *ctx, int vcpu_id)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* _CPC: Continuous Performance Control
|
||||
* Hard code a V3 CPC table, describing HWP register interface.
|
||||
*/
|
||||
static void dsdt_write_cpc(void)
|
||||
{
|
||||
dsdt_line("");
|
||||
dsdt_line(" Method (_CPC, 0, NotSerialized)");
|
||||
dsdt_line(" {");
|
||||
dsdt_line(" Return (Package (0x17)");
|
||||
dsdt_line(" {");
|
||||
dsdt_line(" 0x17,");
|
||||
dsdt_line(" 0x03,");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08, 0x00, 0x0000000000000771, 0x04, )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08, 0x08, 0x00000000000000CE, 0x04, )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08, 0x10, 0x0000000000000771, 0x04, )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08, 0x18, 0x0000000000000771, 0x04, )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08, 0x08, 0x0000000000000771, 0x04, )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08, 0x10, 0x0000000000000774, 0x04, )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08, 0x00, 0x0000000000000774, 0x04, )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08, 0x08, 0x0000000000000774, 0x04, )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(SystemMemory, 0x00, 0x00, 0x0000000000000000, , )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(SystemMemory, 0x00, 0x00, 0x0000000000000000, , )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(SystemMemory, 0x00, 0x00, 0x0000000000000000, , )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x40, 0x00, 0x00000000000000E7, 0x04, )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x40, 0x00, 0x00000000000000E8, 0x04, )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x02, 0x01, 0x0000000000000777, 0x04, )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x01, 0x00, 0x0000000000000770, 0x04, )},");
|
||||
dsdt_line(" One,");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x0A, 0x20, 0x0000000000000774, 0x04, )},");
|
||||
dsdt_line(" ResourceTemplate() {Register(FFixedHW, 0x08, 0x18, 0x0000000000000774, 0x04, )},");
|
||||
dsdt_line(" Zero,");
|
||||
dsdt_line(" Zero,");
|
||||
dsdt_line(" Zero");
|
||||
dsdt_line(" })");
|
||||
dsdt_line(" }");
|
||||
}
|
||||
|
||||
void pm_write_dsdt(struct vmctx *ctx, int ncpu)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
bool is_cpc = false;
|
||||
uint8_t px_cnt;
|
||||
|
||||
/* Scope (_PR) */
|
||||
dsdt_line("");
|
||||
|
@ -364,6 +407,26 @@ void pm_write_dsdt(struct vmctx *ctx, int ncpu)
|
|||
}
|
||||
}
|
||||
|
||||
ret = get_vcpu_px_cnt(ctx, i, &px_cnt);
|
||||
if (ret == 0 && px_cnt == 0) {
|
||||
/* px_cnt = 0 Indicates vcpu supports continuous pstate.
|
||||
* Then we can write _CPC
|
||||
*/
|
||||
is_cpc = true;
|
||||
}
|
||||
|
||||
if (is_cpc) {
|
||||
if (i == 0) {
|
||||
dsdt_write_cpc();
|
||||
} else {
|
||||
dsdt_line(" Method (_CPC, 0, NotSerialized)");
|
||||
dsdt_line(" {");
|
||||
dsdt_line(" Return (^^PR00._CPC)");
|
||||
dsdt_line(" }");
|
||||
dsdt_line("");
|
||||
}
|
||||
}
|
||||
|
||||
dsdt_line(" }");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue