在2024年2月27日二月 上午3:14,maobibo写道: > On 2024/2/27 上午4:02, Jiaxun Yang wrote: >> >> >> 在2024年2月26日二月 上午8:04,maobibo写道: >>> On 2024/2/26 下午2:12, Huacai Chen wrote: >>>> On Mon, Feb 26, 2024 at 10:04 AM maobibo <maobibo@xxxxxxxxxxx> wrote: >>>>> >>>>> >>>>> >>>>> On 2024/2/24 下午5:13, Huacai Chen wrote: >>>>>> Hi, Bibo, >>>>>> >>>>>> On Thu, Feb 22, 2024 at 11:28 AM Bibo Mao <maobibo@xxxxxxxxxxx> wrote: >>>>>>> >>>>>>> Instruction cpucfg can be used to get processor features. And there >>>>>>> is trap exception when it is executed in VM mode, and also it is >>>>>>> to provide cpu features to VM. On real hardware cpucfg area 0 - 20 >>>>>>> is used. Here one specified area 0x40000000 -- 0x400000ff is used >>>>>>> for KVM hypervisor to privide PV features, and the area can be extended >>>>>>> for other hypervisors in future. This area will never be used for >>>>>>> real HW, it is only used by software. >>>>>> After reading and thinking, I find that the hypercall method which is >>>>>> used in our productive kernel is better than this cpucfg method. >>>>>> Because hypercall is more simple and straightforward, plus we don't >>>>>> worry about conflicting with the real hardware. >>>>> No, I do not think so. cpucfg is simper than hypercall, hypercall can >>>>> be in effect when system runs in guest mode. In some scenario like TCG >>>>> mode, hypercall is illegal intruction, however cpucfg can work. >>>> Nearly all architectures use hypercall except x86 for its historical >>> Only x86 support multiple hypervisors and there is multiple hypervisor >>> in x86 only. It is an advantage, not historical reason. >> >> I do believe that all those stuff should not be exposed to guest user space >> for security reasons. > Can you add PLV checking when cpucfg 0x40000000-0x400000FF is emulated? > if it is user mode return value is zero and it is kernel mode emulated > value will be returned. It can avoid information leaking. Please don’t do insane stuff here, applications are not expecting exception from cpucfg. > >> >> Also for different implementations of hypervisors they may have different >> PV features behavior, using hypcall to perform feature detection >> can pass more information to help us cope with hypervisor diversity. > How do different hypervisors can be detected firstly? On x86 MSR is > used for all hypervisors detection and on ARM64 hyperv used > acpi_gbl_FADT and kvm use smc forcely, host mode can execute smc > instruction without exception on ARM64. That’s hypcall ABI design choices, those information can come from firmware or privileged CSRs on LoongArch. > > I do not know why hypercall is better than cpucfg on LoongArch, cpucfg > is basic intruction however hypercall is not, it is part of LVZ feature. KVM can only work with LVZ right? > >>> >>>> reasons. If we use CPUCFG, then the hypervisor information is >>>> unnecessarily leaked to userspace, and this may be a security issue. >>>> Meanwhile, I don't think TCG mode needs PV features. >>> Besides PV features, there is other features different with real hw such >>> as virtio device, virtual interrupt controller. >> >> Those are *device* level information, they must be passed in firmware >> interfaces to keep processor emulation sane. > File arch/x86/hyperv/hv_apic.c can be referenced, apic features comes > from ms_hyperv.hints and HYPERV_CPUID_ENLIGHTMENT_INFO cpuid info, not > must be passed by firmware interface. That’s not KVM, that’s Hyper V. At Linux Kernel we enjoy the benefits of better modularity on device abstractions, please don’t break it. Thanks > > Regards > Bibo Mao >> >> Thanks >> >>> >>> Regards >>> Bibo Mao >>> >>>> >>>> I consulted with Jiaxun before, and maybe he can give some more comments. >>>> >>>>> >>>>> Extioi virtualization extension will be added later, cpucfg can be used >>>>> to get extioi features. It is unlikely that extioi driver depends on >>>>> PARA_VIRT macro if hypercall is used to get features. >>>> CPUCFG is per-core information, if we really need something about >>>> extioi, it should be in iocsr (LOONGARCH_IOCSR_FEATURES). >>>> >>>> >>>> Huacai >>>> >>>>> >>>>> Regards >>>>> Bibo Mao >>>>> >>>>>> >>>>>> Huacai >>>>>> >>>>>>> >>>>>>> Signed-off-by: Bibo Mao <maobibo@xxxxxxxxxxx> >>>>>>> --- >>>>>>> arch/loongarch/include/asm/inst.h | 1 + >>>>>>> arch/loongarch/include/asm/loongarch.h | 10 ++++++ >>>>>>> arch/loongarch/kvm/exit.c | 46 +++++++++++++++++--------- >>>>>>> 3 files changed, 41 insertions(+), 16 deletions(-) >>>>>>> >>>>>>> diff --git a/arch/loongarch/include/asm/inst.h b/arch/loongarch/include/asm/inst.h >>>>>>> index d8f637f9e400..ad120f924905 100644 >>>>>>> --- a/arch/loongarch/include/asm/inst.h >>>>>>> +++ b/arch/loongarch/include/asm/inst.h >>>>>>> @@ -67,6 +67,7 @@ enum reg2_op { >>>>>>> revhd_op = 0x11, >>>>>>> extwh_op = 0x16, >>>>>>> extwb_op = 0x17, >>>>>>> + cpucfg_op = 0x1b, >>>>>>> iocsrrdb_op = 0x19200, >>>>>>> iocsrrdh_op = 0x19201, >>>>>>> iocsrrdw_op = 0x19202, >>>>>>> diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h >>>>>>> index 46366e783c84..a1d22e8b6f94 100644 >>>>>>> --- a/arch/loongarch/include/asm/loongarch.h >>>>>>> +++ b/arch/loongarch/include/asm/loongarch.h >>>>>>> @@ -158,6 +158,16 @@ >>>>>>> #define CPUCFG48_VFPU_CG BIT(2) >>>>>>> #define CPUCFG48_RAM_CG BIT(3) >>>>>>> >>>>>>> +/* >>>>>>> + * cpucfg index area: 0x40000000 -- 0x400000ff >>>>>>> + * SW emulation for KVM hypervirsor >>>>>>> + */ >>>>>>> +#define CPUCFG_KVM_BASE 0x40000000UL >>>>>>> +#define CPUCFG_KVM_SIZE 0x100 >>>>>>> +#define CPUCFG_KVM_SIG CPUCFG_KVM_BASE >>>>>>> +#define KVM_SIGNATURE "KVM\0" >>>>>>> +#define CPUCFG_KVM_FEATURE (CPUCFG_KVM_BASE + 4) >>>>>>> + >>>>>>> #ifndef __ASSEMBLY__ >>>>>>> >>>>>>> /* CSR */ >>>>>>> diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c >>>>>>> index 923bbca9bd22..6a38fd59d86d 100644 >>>>>>> --- a/arch/loongarch/kvm/exit.c >>>>>>> +++ b/arch/loongarch/kvm/exit.c >>>>>>> @@ -206,10 +206,37 @@ int kvm_emu_idle(struct kvm_vcpu *vcpu) >>>>>>> return EMULATE_DONE; >>>>>>> } >>>>>>> >>>>>>> -static int kvm_trap_handle_gspr(struct kvm_vcpu *vcpu) >>>>>>> +static int kvm_emu_cpucfg(struct kvm_vcpu *vcpu, larch_inst inst) >>>>>>> { >>>>>>> int rd, rj; >>>>>>> unsigned int index; >>>>>>> + >>>>>>> + rd = inst.reg2_format.rd; >>>>>>> + rj = inst.reg2_format.rj; >>>>>>> + ++vcpu->stat.cpucfg_exits; >>>>>>> + index = vcpu->arch.gprs[rj]; >>>>>>> + >>>>>>> + /* >>>>>>> + * By LoongArch Reference Manual 2.2.10.5 >>>>>>> + * Return value is 0 for undefined cpucfg index >>>>>>> + */ >>>>>>> + switch (index) { >>>>>>> + case 0 ... (KVM_MAX_CPUCFG_REGS - 1): >>>>>>> + vcpu->arch.gprs[rd] = vcpu->arch.cpucfg[index]; >>>>>>> + break; >>>>>>> + case CPUCFG_KVM_SIG: >>>>>>> + vcpu->arch.gprs[rd] = *(unsigned int *)KVM_SIGNATURE; >>>>>>> + break; >>>>>>> + default: >>>>>>> + vcpu->arch.gprs[rd] = 0; >>>>>>> + break; >>>>>>> + } >>>>>>> + >>>>>>> + return EMULATE_DONE; >>>>>>> +} >>>>>>> + >>>>>>> +static int kvm_trap_handle_gspr(struct kvm_vcpu *vcpu) >>>>>>> +{ >>>>>>> unsigned long curr_pc; >>>>>>> larch_inst inst; >>>>>>> enum emulation_result er = EMULATE_DONE; >>>>>>> @@ -224,21 +251,8 @@ static int kvm_trap_handle_gspr(struct kvm_vcpu *vcpu) >>>>>>> er = EMULATE_FAIL; >>>>>>> switch (((inst.word >> 24) & 0xff)) { >>>>>>> case 0x0: /* CPUCFG GSPR */ >>>>>>> - if (inst.reg2_format.opcode == 0x1B) { >>>>>>> - rd = inst.reg2_format.rd; >>>>>>> - rj = inst.reg2_format.rj; >>>>>>> - ++vcpu->stat.cpucfg_exits; >>>>>>> - index = vcpu->arch.gprs[rj]; >>>>>>> - er = EMULATE_DONE; >>>>>>> - /* >>>>>>> - * By LoongArch Reference Manual 2.2.10.5 >>>>>>> - * return value is 0 for undefined cpucfg index >>>>>>> - */ >>>>>>> - if (index < KVM_MAX_CPUCFG_REGS) >>>>>>> - vcpu->arch.gprs[rd] = vcpu->arch.cpucfg[index]; >>>>>>> - else >>>>>>> - vcpu->arch.gprs[rd] = 0; >>>>>>> - } >>>>>>> + if (inst.reg2_format.opcode == cpucfg_op) >>>>>>> + er = kvm_emu_cpucfg(vcpu, inst); >>>>>>> break; >>>>>>> case 0x4: /* CSR{RD,WR,XCHG} GSPR */ >>>>>>> er = kvm_handle_csr(vcpu, inst); >>>>>>> -- >>>>>>> 2.39.3 >>>>>>> >>>>> >>>>> >> -- - Jiaxun