diff --git a/Makefile b/Makefile index f8b4a6a0f..e52101f6a 100644 --- a/Makefile +++ b/Makefile @@ -116,6 +116,7 @@ C_SRCS += arch/x86/guest/vmsr.c C_SRCS += arch/x86/guest/vioapic.c C_SRCS += arch/x86/guest/instr_emul.c C_SRCS += arch/x86/guest/ucode.c +C_SRCS += arch/x86/guest/pm.c C_SRCS += lib/spinlock.c C_SRCS += lib/udelay.c C_SRCS += lib/strnlen.c diff --git a/arch/x86/cpu.c b/arch/x86/cpu.c index dca2c49c4..2a1b488e2 100644 --- a/arch/x86/cpu.c +++ b/arch/x86/cpu.c @@ -36,7 +36,6 @@ #include #include #include -#include #ifdef CONFIG_EFI_STUB extern uint32_t efi_physical_available_ap_bitmap; diff --git a/arch/x86/cpu_state_tbl.c b/arch/x86/cpu_state_tbl.c index 901c66538..c322dad92 100644 --- a/arch/x86/cpu_state_tbl.c +++ b/arch/x86/cpu_state_tbl.c @@ -28,11 +28,9 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include #include +#include #include -#include /* The table includes cpu px info of Intel A3960 SoC */ struct cpu_px_data px_a3960[] = { @@ -68,9 +66,16 @@ struct cpu_px_data px_j3455[] = { {0x320, 0, 0xA, 0xA, 0x0800, 0x0800} /* P8 */ }; -struct cpu_state_table cpu_state_tbl[] = { - {"Intel(R) Atom(TM) Processor A3960 @ 1.90GHz", 17, px_a3960}, - {"Intel(R) Celeron(R) CPU J3455 @ 1.50GHz", 9, px_j3455} +struct cpu_state_table { + char model_name[64]; + struct cpu_state_info state_info; +} cpu_state_tbl[] = { + {"Intel(R) Atom(TM) Processor A3960 @ 1.90GHz", + {ARRAY_SIZE(px_a3960), px_a3960} + }, + {"Intel(R) Celeron(R) CPU J3455 @ 1.50GHz", + {ARRAY_SIZE(px_j3455), px_j3455} + } }; static int get_state_tbl_idx(char *cpuname) @@ -95,9 +100,10 @@ static int get_state_tbl_idx(char *cpuname) void load_cpu_state_data(void) { int tbl_idx; + struct cpu_state_info *state_info; - boot_cpu_data.px_cnt = 0; - boot_cpu_data.px_data = NULL; + memset(&boot_cpu_data.state_info, 0, + sizeof(struct cpu_state_info)); tbl_idx = get_state_tbl_idx(boot_cpu_data.model_name); if (tbl_idx < 0) { @@ -105,72 +111,15 @@ void load_cpu_state_data(void) return; } - if (!((cpu_state_tbl + tbl_idx)->px_cnt) - || !((cpu_state_tbl + tbl_idx)->px_data)) { - /* The state table must be wrong. */ - return; - } + state_info = &(cpu_state_tbl + tbl_idx)->state_info; - if ((cpu_state_tbl + tbl_idx)->px_cnt > MAX_PSTATE) { - boot_cpu_data.px_cnt = MAX_PSTATE; - } else { - boot_cpu_data.px_cnt = (cpu_state_tbl + tbl_idx)->px_cnt; - } - - boot_cpu_data.px_data = (cpu_state_tbl + tbl_idx)->px_data; - -} - -int validate_pstate(struct vm *vm, uint64_t perf_ctl) -{ - struct cpu_px_data *px_data; - int i, px_cnt; - - if (is_vm0(vm)) { - return 0; - } - - px_cnt = vm->pm.px_cnt; - px_data = vm->pm.px_data; - - if (!px_cnt || !px_data) { - return -1; - } - - for (i = 0; i < px_cnt; i++) { - if ((px_data + i)->control == (perf_ctl & 0xffff)) { - return 0; + if (state_info->px_cnt && state_info->px_data) { + if (state_info->px_cnt > MAX_PSTATE) { + boot_cpu_data.state_info.px_cnt = MAX_PSTATE; + } else { + boot_cpu_data.state_info.px_cnt = state_info->px_cnt; } + + boot_cpu_data.state_info.px_data = state_info->px_data; } - - return -1; -} - -void vm_setup_cpu_px(struct vm *vm) -{ - uint32_t px_data_size; - - vm->pm.px_cnt = 0; - memset(vm->pm.px_data, 0, MAX_PSTATE * sizeof(struct cpu_px_data)); - - if ((!boot_cpu_data.px_cnt) || (!boot_cpu_data.px_data)) { - return; - } - - if (boot_cpu_data.px_cnt > MAX_PSTATE) { - vm->pm.px_cnt = MAX_PSTATE; - } else { - vm->pm.px_cnt = boot_cpu_data.px_cnt; - } - - px_data_size = vm->pm.px_cnt * sizeof(struct cpu_px_data); - - memcpy_s(vm->pm.px_data, px_data_size, - boot_cpu_data.px_data, px_data_size); - -} - -void vm_setup_cpu_state(struct vm *vm) -{ - vm_setup_cpu_px(vm); } diff --git a/arch/x86/guest/pm.c b/arch/x86/guest/pm.c new file mode 100644 index 000000000..b3fa1bed1 --- /dev/null +++ b/arch/x86/guest/pm.c @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +int validate_pstate(struct vm *vm, uint64_t perf_ctl) +{ + struct cpu_px_data *px_data; + int i, px_cnt; + + if (is_vm0(vm)) { + return 0; + } + + px_cnt = vm->pm.px_cnt; + px_data = vm->pm.px_data; + + if (!px_cnt || !px_data) { + return -1; + } + + for (i = 0; i < px_cnt; i++) { + if ((px_data + i)->control == (perf_ctl & 0xffff)) { + return 0; + } + } + + return -1; +} + +static void vm_setup_cpu_px(struct vm *vm) +{ + uint32_t px_data_size; + + vm->pm.px_cnt = 0; + memset(vm->pm.px_data, 0, MAX_PSTATE * sizeof(struct cpu_px_data)); + + if ((!boot_cpu_data.state_info.px_cnt) + || (!boot_cpu_data.state_info.px_data)) { + return; + } + + if (boot_cpu_data.state_info.px_cnt > MAX_PSTATE) { + vm->pm.px_cnt = MAX_PSTATE; + } else { + vm->pm.px_cnt = boot_cpu_data.state_info.px_cnt; + } + + px_data_size = vm->pm.px_cnt * sizeof(struct cpu_px_data); + + memcpy_s(vm->pm.px_data, px_data_size, + boot_cpu_data.state_info.px_data, px_data_size); + +} + +void vm_setup_cpu_state(struct vm *vm) +{ + vm_setup_cpu_px(vm); +} diff --git a/arch/x86/guest/vm.c b/arch/x86/guest/vm.c index f15fcc9bf..9c7428ae9 100644 --- a/arch/x86/guest/vm.c +++ b/arch/x86/guest/vm.c @@ -34,7 +34,6 @@ #include #include #include -#include /* Local variables */ diff --git a/arch/x86/guest/vmsr.c b/arch/x86/guest/vmsr.c index e3ca443ce..b3d0593b5 100644 --- a/arch/x86/guest/vmsr.c +++ b/arch/x86/guest/vmsr.c @@ -33,7 +33,6 @@ #include #include #include -#include /*MRS need to be emulated, the order in this array better as freq of ops*/ static const uint32_t emulated_msrs[] = { diff --git a/common/hypercall.c b/common/hypercall.c index 64deb6ccb..4ef3491c7 100644 --- a/common/hypercall.c +++ b/common/hypercall.c @@ -37,7 +37,6 @@ #include #include #include -#include #define ACRN_DBG_HYCALL 6 diff --git a/include/arch/x86/cpu.h b/include/arch/x86/cpu.h index 2b82e8bac..a23fffc96 100644 --- a/include/arch/x86/cpu.h +++ b/include/arch/x86/cpu.h @@ -236,13 +236,17 @@ enum feature_word { FEATURE_WORDS, }; +struct cpu_state_info { + uint8_t px_cnt; + struct cpu_px_data *px_data; +}; + struct cpuinfo_x86 { uint8_t x86, x86_model; uint64_t physical_address_mask; uint32_t cpuid_leaves[FEATURE_WORDS]; char model_name[64]; - uint8_t px_cnt; - struct cpu_px_data *px_data; + struct cpu_state_info state_info; }; extern struct cpuinfo_x86 boot_cpu_data; @@ -259,6 +263,7 @@ bool is_vapic_supported(void); bool is_vapic_intr_delivery_supported(void); bool is_vapic_virt_reg_supported(void); bool cpu_has_cap(uint32_t bit); +void load_cpu_state_data(void); /* Read control register */ #define CPU_CR_READ(cr, result_ptr) \ diff --git a/include/arch/x86/cpu_state_tbl.h b/include/arch/x86/guest/pm.h similarity index 88% rename from include/arch/x86/cpu_state_tbl.h rename to include/arch/x86/guest/pm.h index 28ad4640d..cd463eebe 100644 --- a/include/arch/x86/cpu_state_tbl.h +++ b/include/arch/x86/guest/pm.h @@ -28,17 +28,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef CPU_STATE_TBL_H -#define CPU_STATE_TBL_H +#ifndef PM_H +#define PM_H -struct cpu_state_table { - char model_name[64]; - uint8_t px_cnt; - struct cpu_px_data *px_data; -}; - -void load_cpu_state_data(void); void vm_setup_cpu_state(struct vm *vm); int validate_pstate(struct vm *vm, uint64_t perf_ctl); -#endif /* CPU_STATE_TBL_H */ +#endif /* PM_H */ diff --git a/include/arch/x86/hv_arch.h b/include/arch/x86/hv_arch.h index 011e73bfd..a29f8ce8c 100644 --- a/include/arch/x86/hv_arch.h +++ b/include/arch/x86/hv_arch.h @@ -41,7 +41,7 @@ #include #include #include -#include +#include #include #include #include