- Siêu lớp và danh mục iOS/Objective-C
- object-c - -1001 lỗi khi NSURLSession vượt qua httpproxy và /etc/hosts
- java - Nhận địa chỉ url bằng lớp mạng
- ios - Âm thanh không phát trong thông báo đẩy
Đây có phải là mã nhân Linux chính xác để sửa đổi không? Làm cách nào tôi có thể thực hiện các thay đổi để mô phỏng mã CPUID và tôi cần thay đổi chức năng nào. Cảm ơn
#include
#include
#include
#include
#include
#include
#include
#include
#include "cpuid.h"
#include "lapic.h"
#include "mmu.h"
#include "dấu vết.h"
#include "pmu.h"
tĩnh u32 xstate_required_size(u64 xstate_bv, bool được nén)
{
int feature_bit = 0;
u32 ret = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET;
xstate_bv &= XFEATURE_MASK_EXTEND;
trong khi (xstate_bv) {
nếu (xstate_bv & 0x1) {
u32 eax, ebx, ecx, edx, offset;
cpuid_count(0xD, feature_bit, &eax, &ebx, &ecx, &edx);
offset = đã nén lại ret : ebx;
ret = max(ret, offset + eax);
}
xstate_bv >>= 1;
feature_bit++;
}
return ret;
}
bool kvm_mpx_supported(void)
{
trả về ((host_xcr0 & (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR))
&& kvm_x86_ops->mpx_supported());
}
EXPORT_SYMBOL_GPL(kvm_mpx_supported);
u64 kvm_supported_xcr0(void)
{
u64 xcr0 = KVM_SUPPORTED_XCR0 & máy chủ_xcr0;
nếu (!kvm_mpx_supported())
xcr0 &= ~(XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR);
trả lại xcr0;
}
#define F(x) bit(X86_FEATURE_##x)
/* Đây là các tính năng rải rác trong cpufeatures.h */
#define KVM_CPUID_BIT_AVX512_4VNNIW 2
#define KVM_CPUID_BIT_AVX512_4FMAPS 3
#define bit KF(x)(KVM_CPUID_BIT_##x)
int kvm_update_cpuid(struct kvm_vcpu *vcpu)
{
cấu trúc kvm_cpuid_entry2 *tốt nhất;
struct kvm_lapic *apic = vcpu->arch.apic;
tốt nhất = kvm_find_cpuid_entry(vcpu, 1, 0);
nếu (!tốt nhất)
return 0;
/* Cập nhật bit OSXSAVE */
if (boot_cpu_has(X86_FEATURE_XSAVE) && best->function == 0x1) {
tốt nhất->ecx &= ~F(OSXSAVE);
nếu (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE))
tốt nhất->ecx |= F(OSXSAVE);
}
tốt nhất->edx &= ~F(APIC);
nếu (vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE)
tốt nhất->edx |= F(APIC);
nếu (apic) {
if (tốt nhất->ecx & F(TSC_DEADLINE_TIMER))
apic->lapic_timer.timer_mode_mask = 3 << 17;
khác
apic->lapic_timer.timer_mode_mask = 1 << 17;
}
tốt nhất = kvm_find_cpuid_entry(vcpu, 7, 0);
nếu (tốt nhất) {
/* Cập nhật bit OSPKE */
if (boot_cpu_has(X86_FEATURE_PKU) && best->function == 0x7) {
tốt nhất->ecx &= ~F(OSPKE);
nếu (kvm_read_cr4_bits(vcpu, X86_CR4_PKE))
tốt nhất->ecx |= F(OSPKE);
}
}
tốt nhất = kvm_find_cpuid_entry(vcpu, 0xD, 0);
nếu (!tốt nhất) {
vcpu->arch.guest_supported_xcr0 = 0;
vcpu->arch.guest_xstate_size = XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET;
} khác {
vcpu->arch.guest_supported_xcr0 =
(tốt nhất->eax | ((u64)tốt nhất->edx << 32)) &
kvm_supported_xcr0();
vcpu->arch.guest_xstate_size = tốt nhất->ebx =
xstate_required_size(vcpu->arch.xcr0, false);
}
tốt nhất = kvm_find_cpuid_entry(vcpu, 0xD, 1);
if (tốt nhất && (tốt nhất->eax & (F(XSAVES) | F(XSAVEC))))
best->ebx = xstate_required_size(vcpu->arch.xcr0, true);
/*
* Mã hiện tại giả sử địa chỉ ảo là 48-bit hoặc 57-bit trong
* kiểm tra địa chỉ chuẩn sẽ thoát nếu nó được thay đổi.
*/
tốt nhất = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
nếu (tốt nhất) {
int vaddr_bits = (best->eax & 0xff00) >> 8;
if (vaddr_bits != 48 && vaddr_bits != 57 && vaddr_bits != 0)
trả về -EINVAL;
}
/* Cập nhật độ rộng địa chỉ vật lý */
vcpu->arch.maxphyaddr = cpuid_query_maxphyaddr(vcpu);
kvm_mmu_reset_context(vcpu);
kvm_pmu_refresh(vcpu);
return 0;
}
int tĩnh is_efer_nx(void)
{
unsigned long long efer = 0;
rdmsrl_safe(MSR_EFER, &efer);
trả lại efer & EFER_NX;
}
khoảng trống tĩnh cpuid_fix_nx_cap(struct kvm_vcpu *vcpu)
{
int i;
struct kvm_cpuid_entry2 *e, *entry;
mục nhập = NULL;
for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
e = &vcpu->arch.cpuid_entries[i];
nếu (e->hàm == 0x80000001) {
mục = e;
phá vỡ;
}
}
if (entry && (entry->edx & F(NX)) && !is_efer_nx()) {
mục->edx &= ~F(NX);
printk(KERN_INFO "kvm: khả năng NX của khách đã bị loại bỏ\n");
}
}
int cpuid_query_maxphyaddr(struct kvm_vcpu *vcpu)
{
cấu trúc kvm_cpuid_entry2 *tốt nhất;
tốt nhất = kvm_find_cpuid_entry(vcpu, 0x80000000, 0);
if (!tốt nhất || tốt nhất->eax < 0x80000008)
đã không tìm thấy;
tốt nhất = kvm_find_cpuid_entry(vcpu, 0x80000008, 0);
nếu (tốt nhất)
trả về tốt nhất->eax & 0xff;
không_tìm thấy:
trả lại 36;
}
XUẤT_SYMBOL_GPL(cpuid_query_maxphyaddr);
/* khi tiến trình vùng người dùng cũ lấp đầy mô-đun hạt nhân mới */
int kvm_vcpu_ioctl_set_cpuid(struct kvm_vcpu *vcpu,
cấu trúc kvm_cpuid *cpuid,
struct kvm_cpuid_entry __user *mục)
{
int r, tôi;
struct kvm_cpuid_entry *cpuid_entries = NULL;
r = -E2BIG;
nếu (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
đi ra ngoài;
r = -ENOMEM;
nếu (cpuid->nent) {
cpuid_entries = vmalloc(sizeof(struct kvm_cpuid_entry) *
cpuid->nent);
nếu (! cpuid_entries)
đi ra ngoài;
r = -EFAULT;
if (copy_from_user(cpuid_entries, mục,
cpuid->nent * sizeof(struct kvm_cpuid_entry)))
đi ra ngoài;
}
for (i = 0; i < cpuid->nent; i++) {
vcpu->arch.cpuid_entries[i].function = cpuid_entries[i].function;
vcpu->arch.cpuid_entries[i].eax = cpuid_entries[i].eax;
vcpu->arch.cpuid_entries[i].ebx = cpuid_entries[i].ebx;
vcpu->arch.cpuid_entries[i].ecx = cpuid_entries[i].ecx;
vcpu->arch.cpuid_entries[i].edx = cpuid_entries[i].edx;
vcpu->arch.cpuid_entries[i].index = 0;
vcpu->arch.cpuid_entries[i].flags = 0;
vcpu->arch.cpuid_entries[i].padding[0] = 0;
vcpu->arch.cpuid_entries[i].padding[1] = 0;
vcpu->arch.cpuid_entries[i].padding[2] = 0;
}
vcpu->arch.cpuid_nent = cpuid->nent;
cpuid_fix_nx_cap(vcpu);
kvm_apic_set_version(vcpu);
kvm_x86_ops->cpuid_update(vcpu);
r = kvm_update_cpuid(vcpu);
ngoài:
vfree(cpuid_entries);
trả lại r;
}
int kvm_vcpu_ioctl_set_cpuid2(struct kvm_vcpu *vcpu,
cấu trúc kvm_cpuid2 *cpuid,
struct kvm_cpuid_entry2 __user *mục)
{
int r;
r = -E2BIG;
nếu (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
đi ra ngoài;
r = -EFAULT;
if (copy_from_user(&vcpu->arch.cpuid_entries, mục,
cpuid->nent * sizeof(struct kvm_cpuid_entry2)))
đi ra ngoài;
vcpu->arch.cpuid_nent = cpuid->nent;
kvm_apic_set_version(vcpu);
kvm_x86_ops->cpuid_update(vcpu);
r = kvm_update_cpuid(vcpu);
ngoài:
trả lại r;
}
int kvm_vcpu_ioctl_get_cpuid2(struct kvm_vcpu *vcpu,
cấu trúc kvm_cpuid2 *cpuid,
struct kvm_cpuid_entry2 __user *mục)
{
int r;
r = -E2BIG;
if (cpuid->nent < vcpu->arch.cpuid_nent)
đi ra ngoài;
r = -EFAULT;
if (copy_to_user(entry, &vcpu->arch.cpuid_entries,
vcpu->arch.cpuid_nent * sizeof(struct kvm_cpuid_entry2)))
đi ra ngoài;
return 0;
ngoài:
cpuid->nent = vcpu->arch.cpuid_nent;
trả lại r;
}
tĩnh void cpuid_mask(u32 *word, int wordnum)
{
*word &= boot_cpu_data.x86_capability[wordnum];
}
static void do_cpuid_1_ent(struct kvm_cpuid_entry2 *entry, hàm u32,
chỉ số u32)
{
mục->chức năng = chức năng;
mục-> chỉ mục = chỉ mục;
cpuid_count(entry->function, entry->index,
&entry->eax, &entry->ebx, &entry->ecx, &entry->edx);
mục-> cờ = 0;
}
int tĩnh __do_cpuid_ent_emulated(struct kvm_cpuid_entry2 *entry,
u32 func, chỉ mục u32, int *nent, int maxnent)
{
chuyển đổi (chức năng) {
trường hợp 0:
entry->eax = 1; /* hiện tại chỉ có một lá */
++*nent;
phá vỡ;
trường hợp 1:
mục->ecx = F(MOVBE);
++*nent;
phá vỡ;
default:
phá vỡ;
}
mục->hàm = func;
mục-> chỉ mục = chỉ mục;
return 0;
}
int nội tuyến tĩnh __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, hàm u32,
chỉ mục u32, int *nent, int maxnent)
{
int r;
chưa ký f_nx = is_efer_nx() ? F(NX) : 0;
#ifdef CONFIG_X86_64
f_gbpages chưa được ký = (kvm_x86_ops->get_lpage_level() == PT_PDPE_LEVEL)
?F(GBPAGES): 0;
không dấu f_lm = F(LM);
#else
f_gbpages không dấu = 0;
không dấu f_lm = 0;
#endif
chưa ký f_rdtscp = kvm_x86_ops->rdtscp_supported() ? F(RDTSCP) : 0;
chưa ký f_invpcid = kvm_x86_ops->invpcid_supported() ? F(INVPCID) : 0;
không dấu f_mpx = kvm_mpx_supported() ? F(MPX) : 0;
chưa ký f_xsaves = kvm_x86_ops->xsaves_supported() ? F(XSAVES) : 0;
/* cpuid 1.edx */
const u32 kvm_cpuid_1_edx_x86_features =
F(FPU) | F(VME) F(DE) |
F(TSC) | F(MSR) F(PAE) |
F(CX8) | F(APIC) 0 /* Dự trữ */ |
F(MTRR) | F(PGE) F(MCA) |
F(PAT) | F(PSE36) |
0 /* Dành riêng, DS, ACPI */ F(MMX) |
F(FXSR) | F(XMM) F(XMM2) F(TỰ TIN) |
0 /* HTT, TM, Dự trữ, PBE */;
/* cpuid 0x80000001.edx */
const u32 kvm_cpuid_8000_0001_edx_x86_features =
F(FPU) | F(VME) F(DE) |
F(TSC) | F(MSR) F(PAE) |
F(CX8) | F(APIC) 0 /* Dành riêng */ |
F(MTRR) | F(PGE) F(MCA) |
F(PAT) | F(PSE36) 0 /* Dành riêng */ |
f_nx | 0 /* Dành riêng */ F(MMXEXT) |
F(FXSR) | F(FXSR_OPT) |
0 /* Dành riêng */ f_lm F(3DNOWEXT) |
/* cpuid 1.ecx */
const u32 kvm_cpuid_1_ecx_x86_features =
/* LƯU Ý: MONITOR (và MWAIT) được mô phỏng dưới dạng NOP,
* nhưng *không* được quảng cáo cho khách qua CPUID */
F(XMM3) | F(PCLMULQDQ) 0 /* DTES64, GIÁM SÁT */ |
0 /* DS-CPL, VMX, SMX, EST */ |
0 /* TM2 */ | F(SSSE3) 0 /* CNXT-ID */ 0 /* Dành riêng */ |
F(FMA) | F(CX16) 0 /* xTPR Cập nhật, PDCM */ |
F(PCID) | 0 /* Dự trữ, DCA */ F(XMM4_1) |
F(XMM4_2) | F(X2APIC) F(MOVBE) F(POPCNT) |
0 /* Dành riêng*/ | F(AES) F(XSAVE) 0 /* OSXSAVE */ |
F(F16C) | F(RDDRAND);
/* cpuid 0x80000001.ecx */
const u32 kvm_cpuid_8000_0001_ecx_x86_features =
F(LAHF_LM) | F(CMP_LEGACY) 0 /*SVM*/ 0 /* ExtApicSpace */ |
F(CR8_LEGACY) | F(ABM) F(SSE4A) F(MISALIGNSSE) |
F(3DNOWPREFETCH) | F(OSVW) |
0 /* SKINIT, WDT, LWP */ F(FMA4) F(TBM);
/* cpuid 0xC0000001.edx */
const u32 kvm_cpuid_C000_0001_edx_x86_features =
F(XSTORE) | F(XSTORE_EN) F(XCRYPT) F(XCRYPT_EN) |
F(ACE2) | F(ACE2_EN) F(PHE) |
F(PMM) | F(PMM_EN);
/* cpuid 7.0.ebx */
const u32 kvm_cpuid_7_0_ebx_x86_features =
F(FSGSBASE) | F(BMI1) F(HLE) |
F(BMI2) | F(ERMS) | F_invpcid |
F(ADX) | F(SMAP) F(AVX512IFMA) |
F(AVX512ER) | F(AVX512CD) | F(CLFUSHOPT) F(CLWB) |
F(SHA_NI) | F(AVX512BW) | F(AVX512VL);
/* cpuid 0xD.1.eax */
const u32 kvm_cpuid_D_1_eax_x86_features =
F(XSAVEOPT) | F(XSAVEC) F(XGETBV1) |
/* cpuid 7.0.ecx*/
const u32 kvm_cpuid_7_0_ecx_x86_features =
F(AVX512VBMI) F(LA57) |
0 /*OSPKE*/ F(AVX512_VPOPCNTDQ);
/* cpuid 7.0.edx*/
const u32 kvm_cpuid_7_0_edx_x86_features =
KF(AVX512_4VNNIW) | KF(AVX512_4FMAPS);
/* tất cả lệnh gọi tới cpuid_count() phải được thực hiện trên cùng một cpu */
get_cpu();
r = -E2BIG;
nếu (*nent >= maxnent)
đi ra ngoài;
do_cpuid_1_ent(mục nhập, hàm, chỉ mục);
++*nent;
chuyển đổi (chức năng) {
trường hợp 0:
mục->eax = min(entry->eax, (u32)0xd);
phá vỡ;
trường hợp 1:
mục->edx &= kvm_cpuid_1_edx_x86_features;
cpuid_mask(&entry->edx, CPUID_1_EDX);
mục->ecx &= kvm_cpuid_1_ecx_x86_features;
cpuid_mask(&entry->ecx, CPUID_1_ECX);
/* chúng tôi hỗ trợ mô phỏng x2apic ngay cả khi máy chủ không hỗ trợ
* đó là do chúng tôi mô phỏng x2apic trong phần mềm */
mục->ecx |= F(X2APIC);
phá vỡ;
/* mục nhập hàm 2 là TRANG TRẠNG Nghĩa là, các lệnh cpuid được lặp lại.
* có thể trả về các giá trị khác nhau. Điều này buộc chúng ta phải get_cpu() trước đó.
* đưa ra lệnh đầu tiên và cũng để mô phỏng hành vi gây phiền nhiễu này
* trong kvm_emulate_cpuid() sử dụng KVM_CPUID_FLAG_STATE_READ_NEXT */
trường hợp 2: {
int t, lần = entry->eax & 0xff;
mục->cờ |= KVM_CPUID_FLAG_STATEFUL_FUNC;
mục->cờ |= KVM_CPUID_FLAG_STATE_READ_NEXT;
for (t = 1; t < lần; ++t) {
nếu (*nent >= maxnent)
đi ra ngoài;
do_cpuid_1_ent(&entry[t], hàm, 0);
mục [t].flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
++*nent;
}
phá vỡ;
}
/* hàm 4 có chỉ mục bổ sung */
trường hợp 4: {
int tôi, cache_type;
mục->cờ |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
/* đọc thêm mục cho đến khi cache_type bằng 0 */
vì (i = 1; ; ++i) {
nếu (*nent >= maxnent)
đi ra ngoài;
cache_type = entry[i - 1].eax & 0x1f;
nếu (!cache_type)
phá vỡ;
do_cpuid_1_ent(&entry[i], hàm, i);
entry[i].flags |=
KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
++*nent;
}
phá vỡ;
}
trường hợp 6: /* Quản lý nhiệt */
mục->eax = 0x4; /* cho phép ARAT */
mục->ebx = 0;
mục->ecx = 0;
mục->edx = 0;
phá vỡ;
trường hợp 7: {
mục->cờ |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
/* Che dấu ebx chống lại khả năng của từ máy chủ 9 */
nếu (chỉ mục == 0) {
mục->ebx &= kvm_cpuid_7_0_ebx_x86_features;
cpuid_mask(&entry->ebx, CPUID_7_0_EBX);
// TSC_ADJUST được mô phỏng
mục->ebx |= F(TSC_ADJUST);
mục->ecx &= kvm_cpuid_7_0_ecx_x86_features;
cpuid_mask(&entry->ecx, CPUID_7_ECX);
/* PKU chưa được triển khai cho phân trang bóng */
if (!tdp_enabled || !boot_cpu_has(X86_FEATURE_OSPKE))
mục->ecx &= ~F(PKU);
mục->edx &= kvm_cpuid_7_0_edx_x86_features;
entry->edx &= get_scattered_cpuid_leaf(7, 0, CPUID_EDX);
} khác {
mục->ebx = 0;
mục->ecx = 0;
mục->edx = 0;
}
mục->eax = 0;
phá vỡ;
}
trường hợp 9:
phá vỡ;
trường hợp 0xa: { /* Giám sát hiệu suất kiến trúc */
giới hạn cấu trúc x86_pmu_capability;
liên kết cpuid10_eax eax;
liên đoàn cpuid10_edx edx;
perf_get_x86_pmu_capability(&cap);
/*
* Chỉ hỗ trợ pmu kiến trúc khách trên máy chủ
* với pmu kiến trúc.
*/
nếu (!cap.version)
bộ nhớ(&cap, 0, sizeof(cap));
eax.split.version_id = min(cap.version, 2);
eax.split.num_counters = cap.num_counters_gp;
eax.split.bit_width = cap.bit_width_gp;
eax.split.mask_length = cap.events_mask_len;
edx.split.num_counters_fixed = cap.num_counters_fixed;
edx.split.bit_width_fixed = cap.bit_width_fixed;
edx.split.reserved = 0;
mục->eax = eax.full;
mục->ebx = cap.events_mask;
mục->ecx = 0;
mục->edx = edx.full;
phá vỡ;
}
/* Hàm 0xb có chỉ mục bổ sung */
trường hợp 0xb: {
int tôi, cấp_type;
mục->cờ |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
/* đọc thêm mục cho đến khi Level_type bằng 0 */
vì (i = 1; ; ++i) {
nếu (*nent >= maxnent)
đi ra ngoài;
cấp_type = mục [i - 1].ecx & 0xff00;
nếu (!level_type)
phá vỡ;
do_cpuid_1_ent(&entry[i], hàm, i);
entry[i].flags |=
KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
++*nent;
}
phá vỡ;
}
trường hợp 0xd: {
int idx, tôi;
u64 được hỗ trợ = kvm_supported_xcr0();
mục->eax &= được hỗ trợ;
entry->ebx = xstate_required_size(được hỗ trợ, sai);
mục->ecx = mục->ebx;
entry->edx &= được hỗ trợ >> 32;
mục->cờ |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
nếu (!được hỗ trợ)
phá vỡ;
cho (idx = 1, i = 1; idx < 64; ++idx) {
mặt nạ u64 = ((u64)1 << idx);
nếu (*nent >= maxnent)
đi ra ngoài;
do_cpuid_1_ent(&entry[i], hàm, idx);
nếu (idx == 1) {
entry[i].eax &= kvm_cpuid_D_1_eax_x86_features;
cpuid_mask(&entry[i].eax, CPUID_D_1_EAX);
entry[i].ebx = 0;
if (entry[i].eax & (F(XSAVES)|F(XSAVEC)))
entry[i].ebx =
xstate_required_size(được hỗ trợ,
ĐÚNG VẬY);
} khác {
if (entry[i].eax == 0 || !(được hỗ trợ & mặt nạ))
continue;
if (WARN_ON_ONCE(entry[i].ecx & 1))
continue;
}
entry[i].ecx = 0;
entry[i].edx = 0;
entry[i].flags |=
KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
++*nent;
++tôi;
}
phá vỡ;
}
trường hợp KVM_CPUID_SIGNATURE: {
chữ ký const char tĩnh [12] = "KVMKVMKVM\0\0";
const u32 *sigptr = (const u32 *)chữ ký;
mục->eax = KVM_CPUID_FEATURES;
mục->ebx = sigptr[0];
mục->ecx = sigptr[1];
entry->edx = sigptr[2];
phá vỡ;
}
trường hợp KVM_CPUID_FEATURES:
mục->eax = (1 << KVM_FEATURE_CLOCKSOURCE) |
(1 << KVM_FEATURE_NOP_IO_DELAY) |
(1 << KVM_FEATURE_CLOCKSOURCE2) |
(1 << KVM_FEATURE_ASYNC_PF) |
(1 << KVM_FEATURE_PV_EOI) |
(1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT) |
(1 << KVM_FEATURE_PV_UNHALT);
nếu (lịch_info_on())
mục->eax |= (1 << KVM_FEATURE_STEAL_TIME);
mục->ebx = 0;
mục->ecx = 0;
mục->edx = 0;
phá vỡ;
trường hợp 0x80000000:
mục->eax = min(entry->eax, 0x8000001a);
phá vỡ;
trường hợp 0x80000001:
mục->edx &= kvm_cpuid_8000_0001_edx_x86_features;
cpuid_mask(&entry->edx, CPUID_8000_0001_EDX);
mục->ecx &= kvm_cpuid_8000_0001_ecx_x86_features;
cpuid_mask(&entry->ecx, CPUID_8000_0001_ECX);
phá vỡ;
trường hợp 0x80000007: /* Quản lý nguồn nâng cao */
/* TSC bất biến là CPUID.80000007H:EDX[8] */
mục->edx &= (1 << 8);
/* che dấu máy chủ */
entry->edx &= boot_cpu_data.x86_power;
mục->eax = mục->ebx = mục->ecx = 0;
phá vỡ;
trường hợp 0x80000008: {
unsigned g_phys_as = (entry->eax >> 16) & 0xff;
unsigned virt_as = max((entry->eax >> 8) & 0xff, 48U);
phys_as không dấu = entry->eax & 0xff;
nếu (!g_phys_as)
g_phys_as = Phys_as;
mục->eax = g_phys_as | (virt_as << 8);
mục->ebx = mục->edx = 0;
phá vỡ;
}
trường hợp 0x80000019:
mục->ecx = mục->edx = 0;
phá vỡ;
trường hợp 0x8000001a:
phá vỡ;
trường hợp 0x8000001d:
phá vỡ;
/*Thêm hỗ trợ cho lệnh CPUID của Centaur*/
trường hợp 0xC0000000:
/*Bây giờ chỉ hỗ trợ tối đa 0xC0000004*/
mục->eax = min(entry->eax, 0xC0000004);
phá vỡ;
trường hợp 0xC0000001:
mục->edx &= kvm_cpuid_C000_0001_edx_x86_features;
cpuid_mask(&entry->edx, CPUID_C000_0001_EDX);
phá vỡ;
trường hợp 3: /* Số sê-ri bộ xử lý */
trường hợp 5: /* MONITOR/MWAIT */
trường hợp 0xC0000002:
trường hợp 0xC0000003:
trường hợp 0xC0000004:
default:
entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
phá vỡ;
}
kvm_x86_ops->set_supported_cpuid(hàm, mục nhập);
r = 0;
ngoài:
put_cpu();
trả lại r;
}
int tĩnh do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 func,
u32 idx, int *nent, int maxnent, kiểu int không dấu)
{
nếu (loại == KVM_GET_EMULATED_CPUID)
return __do_cpuid_ent_emulated(entry, func, idx, nent, maxnent);
return __do_cpuid_ent(entry, func, idx, nent, maxnent);
}
#undef F
cấu trúc kvm_cpuid_param {
chức năng u32;
u32idx;
bool has_leaf_count;
bool (*bộ định tính)(const struct kvm_cpuid_param *param);
};
bool tĩnh is_centaur_cpu(const struct kvm_cpuid_param *param)
{
trả về boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR;
}
bool tĩnh sanity_check_entries(struct kvm_cpuid_entry2 __user *entries,
__u32 num_entries, int ioctl_type không dấu)
{
int i;
__u32 đệm[3];
nếu (ioctl_type != KVM_GET_EMULATED_CPUID)
trả về sai;
/*
* Chúng tôi muốn đảm bảo rằng -> phần đệm được chuyển sạch khỏi
* không gian người dùng trong trường hợp chúng tôi muốn sử dụng nó cho việc gì đó trong tương lai.
*
* Đáng buồn thay, điều này không được thực thi đối với KVM_GET_SUPPORTED_CPUID và vì vậy chúng tôi
* chỉ phải hài lòng với phía được mô phỏng /tôi.
* rơi nước mắt.
*/
for (i = 0; i < num_entries; i++) {
if (copy_from_user(pad,entry[i].padding, sizeof(pad)))
trả về đúng sự thật;
if (pad[0] || pad[1] || pad[2])
trả về đúng sự thật;
}
trả về sai;
}
int kvm_dev_ioctl_get_cpuid(struct kvm_cpuid2 *cpuid,
struct kvm_cpuid_entry2 __user *mục,
kiểu int không dấu)
{
cấu trúc kvm_cpuid_entry2 *cpuid_entries;
giới hạn int, nent = 0, r = -E2BIG, i;
chức năng u32;
cấu trúc const tĩnh kvm_cpuid_param param[] = {
{ .func = 0, .has_leaf_count = true },
{ .func = 0x80000000, .has_leaf_count = true },
{ .func = 0xC0000000, .qualifier = is_centaur_cpu, .has_leaf_count = true },
{ .func = KVM_CPUID_SIGNATURE },
{ .func = KVM_CPUID_FEATURES },
};
nếu (cpuid->nent < 1)
đi ra ngoài;
nếu (cpuid->nent > KVM_MAX_CPUID_ENTRIES)
cpuid->nent = KVM_MAX_CPUID_ENTRIES;
if (sanity_check_entries(entries, cpuid->nent, type))
trả về -EINVAL;
r = -ENOMEM;
cpuid_entries = vzalloc(sizeof(struct kvm_cpuid_entry2) * cpuid->nent);
nếu (! cpuid_entries)
đi ra ngoài;
r = 0;
for (i = 0; i < ARRAY_SIZE(param); i++) {
const struct kvm_cpuid_param *ent = ¶m[i];
if (ent->bộ định tính && !ent->bộ định tính(ent))
continue;
r = do_cpuid_ent(&cpuid_entries[nent], ent->func, ent->idx,
&nent, cpuid->nent, loại);
nếu(r)
đi out_free;
if (!ent->has_leaf_count)
continue;
giới hạn = cpuid_entries[nent - 1].eax;
for (func = ent->func + 1; func <= limit && nent < cpuid->nent && r == 0; ++func)
r = do_cpuid_ent(&cpuid_entries[nent], func, ent->idx,
&nent, cpuid->nent, loại);
nếu(r)
đi out_free;
}
r = -EFAULT;
if (copy_to_user(entries, cpuid_entries,
nent * sizeof(struct kvm_cpuid_entry2)))
đi out_free;
cpuid->nent = nent;
r = 0;
out_free:
vfree(cpuid_entries);
ngoài:
trả lại r;
}
int tĩnh move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i)
{
struct kvm_cpuid_entry2 *e = &vcpu->arch.cpuid_entries[i];
cấu trúc kvm_cpuid_entry2 *ej;
int j = i;
int nent = vcpu->arch.cpuid_nent;
e->cờ &= ~KVM_CPUID_FLAG_STATE_READ_NEXT;
/* khi không tìm thấy mục tiếp theo, mục hiện tại[i] sẽ được chọn lại */
LÀM {
j = (j + 1) % nent;
ej = &vcpu->arch.cpuid_entries[j];
} while (ej->function != e->function);
ej->cờ |= KVM_CPUID_FLAG_STATE_READ_NEXT;
trả lại j;
}
/* tìm một mục có hàm khớp, chỉ mục khớp (nếu cần) và mục đó
* nên đọc tiếp theo (nếu nó có trạng thái) */
int tĩnh is_matching_cpuid_entry(struct kvm_cpuid_entry2 *e,
hàm u32, chỉ mục u32)
{
if (e->function != function)
return 0;
if ((e->flags & KVM_CPUID_FLAG_SIGNIFCANT_INDEX) && e->index != chỉ mục)
return 0;
if ((e->flags & KVM_CPUID_FLAG_STATEFUL_FUNC) &&
!(e->cờ & KVM_CPUID_FLAG_STATE_READ_NEXT))
return 0;
return 1;
}
struct kvm_cpuid_entry2 *kvm_find_cpuid_entry(struct kvm_vcpu *vcpu,
hàm u32, chỉ mục u32)
{
int i;
cấu trúc kvm_cpuid_entry2 *tốt nhất = NULL;
for (i = 0; i < vcpu->arch.cpuid_nent; ++i) {
cấu trúc kvm_cpuid_entry2 *e;
e = &vcpu->arch.cpuid_entries[i];
if (is_matching_cpuid_entry(e, hàm, chỉ mục)) {
nếu (e->cờ & KVM_CPUID_FLAG_STATEFUL_FUNC)
move_to_next_stateful_cpuid_entry(vcpu, i);
tốt nhất = e;
phá vỡ;
}
}
trở lại tốt nhất;
}
EXPORT_SYMBOL_GPL(kvm_find_cpuid_entry);
/*
* Nếu không tìm thấy kết quả phù hợp, hãy kiểm tra xem chúng tôi có vượt quá giới hạn của vCPU không
* và thay vào đó trả về nội dung của lá _standard_ hợp lệ cao nhất.
* Điều này nhằm đáp ứng đặc tả CPUID.
*/
cấu trúc tĩnh kvm_cpuid_entry2* check_cpuid_limit(struct kvm_vcpu *vcpu,
hàm u32, chỉ mục u32)
{
cấu trúc kvm_cpuid_entry2 *maxlevel;
maxlevel = kvm_find_cpuid_entry(vcpu, hàm & 0x80000000, 0);
if (!maxlevel || maxlevel->eax >= chức năng)
trả về NULL;
nếu (hàm & 0x80000000) {
maxlevel = kvm_find_cpuid_entry(vcpu, 0, 0);
nếu (! mức tối đa)
trả về NULL;
}
trả về kvm_find_cpuid_entry(vcpu, maxlevel->eax, index);
}
bool kvm_cpuid(struct kvm_vcpu *vcpu, u32 *eax, u32 *ebx,
u32 *ecx, u32 *edx, bool check_limit)
{
hàm u32 = *eax, chỉ mục = *ecx;
cấu trúc kvm_cpuid_entry2 *tốt nhất;
bool entry_found = true;
tốt nhất = kvm_find_cpuid_entry(vcpu, hàm, chỉ mục);
nếu (!tốt nhất) {
entry_found = sai;
nếu (!check_limit)
đi ra ngoài;
tốt nhất = check_cpuid_limit(vcpu, hàm, chỉ mục);
}
ngoài:
nếu (tốt nhất) {
*eax = tốt nhất->eax;
*ebx = tốt nhất->ebx;
*ecx = tốt nhất->ecx;
*edx = tốt nhất->edx;
} else
*eax = *ebx = *ecx = *edx = 0;
trace_kvm_cpuid(hàm, *eax, *ebx, *ecx, *edx, entry_found);
trả lại entry_found;
}
XUẤT_SYMBOL_GPL(kvm_cpuid);
int kvm_emulate_cpuid(struct kvm_vcpu *vcpu)
{
u32 eax, ebx, ecx, edx;
if (cpuid_fault_enabled(vcpu) && !kvm_require_cpl(vcpu, 0))
return 1;
eax = kvm_register_read(vcpu, VCPU_REGS_RAX);
ecx = kvm_register_read(vcpu, VCPU_REGS_RCX);
kvm_cpuid(vcpu, &eax, &ebx, &ecx, &edx, true);
kvm_register_write(vcpu, VCPU_REGS_RAX, eax);
kvm_register_write(vcpu, VCPU_REGS_RBX, ebx);
kvm_register_write(vcpu, VCPU_REGS_RCX, ecx);
kvm_register_write(vcpu, VCPU_REGS_RDX, edx);
trả về kvm_skip_emulated_instruction(vcpu);
}
EXPORT_SYMBOL_GPL(kvm_emulate_cpuid);
Tôi muốn thêm/chỉnh sửa mã vào KVM trong cây linux của bạn (tôi đã sao chép kernel từ github), xây dựng lại kernel và khởi động vào kernel đã sửa đổi và chạy các chương trình chế độ người dùng c như
#include
#include
#include
int
chính(int argc, char **argv)
{
uint32_t eax, ebx, ecx, edx;
__cpuid(0x0, eax, ebx, ecx, edx);
printf("CPUID(0x0).EAX=0x%x\n", eax);
printf("CPUID(0x0).EBX=0x%x\n", ebx);
printf("CPUID(0x0).ECX=0x%x\n", ecx);
printf("CPUID(0x0).EDX=0x%x\n", edx);
return 0;
}
Nhận đầu ra tương tự như
Chuỗi thương hiệu CPUID(0x0) = Chính hãngIntel
CPUID(0x4FFFFFFF)
Chuỗi thương hiệu CPUID(0x0) = MỘT SỐ VĂN BẢN
CPUID(0x4FFFFFFF)
câu trả lời hay nhất
Bản thân hạt nhân không triển khai bất kỳ mô phỏng CPUID cụ thể nào; việc này được triển khai bởi các máy khách KVM, chẳng hạn như QEMU. Ví dụ,đây là mã có liên quan trong QEMU , đã được triển khai cho nhiều thương hiệu bộ xử lý hư cấu, chẳng hạn như "CPU ảo QEMU".
Ngoài ra, mô phỏng KVM CPUID chỉ ảnh hưởng đến các máy ảo được lưu trữ bởi máy chạy kernel đó. Nó không ảnh hưởng đến các ứng dụng không gian người dùng thông thường trên máy đó.
Về linux - Làm thế nào hoặc tệp nào được sửa đổi trong mã mô phỏng CPUID của KVM để báo cáo chuỗi thương hiệu bộ xử lý hư cấu (lá CPUID 0x0)? , chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/47065659/
Tôi đang viết bộ nhớ đệm nhận biết NUMA của các đối tượng lớn (ma trận kép) cho máy chủ 4 ổ cắm. Tôi nhận thấy rằng giao tiếp giữa các socket là điểm nghẽn trong ứng dụng của tôi. Vì vậy, tôi muốn có bộ đệm ma trận riêng cho các luồng trên các ổ cắm khác nhau. Tôi đã hạn chế các chủ đề ở một chủ đề cụ thể
Câu hỏi này đã có câu trả lời ở đây: Đã đóng 12 năm trước. Có thể trùng lặp: Phân tích cú pháp JSON bằng C? Thư viện C nào tốt nhất để xử lý JSON? http://www.j
Tôi đang sử dụng bộ xử lý SpinTax đệ quy như minh họa ở đây, bộ xử lý này hoạt động với các chuỗi nhỏ hơn. Tuy nhiên, khi chuỗi vượt quá 20KB, nó bắt đầu hết bộ nhớ và điều này sẽ trở thành một vấn đề. Nếu tôi có một chuỗi như thế này: {Xin chào|Làm thế nào
Có #define trong C# cho phép tôi biết tại thời điểm biên dịch liệu tôi đang biên dịch cho x86 (Win32) hay x64 (Win64) không? Câu trả lời hay nhất Không có cách nào để thực hiện việc này theo mặc định. Lý do là mã C# không được thiết kế dành riêng cho
Tôi không chắc liệu SO có phải là nơi tốt nhất để đặt câu hỏi này hay không. Nếu không, xin vui lòng cho tôi biết tôi nên truy cập trang web chị em nào. Tôi vừa đọc một bài báo về Công nghệ thực thi tin cậy (TXT) của Intel, trong đó có đoạn văn bản sau mà tôi dường như không thể hiểu được: "Intel đã tạo ra một
Tôi cần một công cụ để thực hiện XSLT đối với các tệp XML rất lớn. Nói rõ hơn, tôi không cần bất kỳ thứ gì để thiết kế, chỉnh sửa hoặc gỡ lỗi XSLT, chỉ cần thực thi chúng. Chuyển đổi tôi đang sử dụng đã được tối ưu hóa tốt, nhưng các tệp lớn khiến công cụ tôi đã thử (
Tôi đang học Apache Camel. Bạn có thể vui lòng giải thích cho tôi sự khác biệt giữa bộ xử lý, thành phần và điểm cuối liên quan đến Apache Camel. Câu trả lời hay nhất Tôi khuyên những ai mới làm quen với Apache Camel nên đọc bài viết này, nó giải thích rất rõ về C
Tôi muốn biết cách đồng bộ hóa trên bộ xử lý Camel. Điều liên quan duy nhất tôi tìm thấy trong tài liệu: Lưu ý rằng không có vấn đề tương tranh hoặc khóa khi
Tôi đã thấy https://issues.apache.org/jira/browse/NIFI-78 này trên jira nhưng nó tham chiếu đến java. Có cách nào để ánh xạ quy trình nifi tới một luồng trên máy chủ để tôi có thể
Tôi có trường hợp sử dụng sau: Trong một ứng dụng, tôi sử dụng một số tin nhắn bằng luồng X, trong đó tôi có triển khai Người tiêu dùng được xác định như thế này: giao diện công cộng Người tiêu dùng { onMessage(
Có mã nào trong bộ xử lý CPU12 cung cấp chức năng KHÔNG đơn giản không? Câu trả lời tốt nhất cho vấn đề này phải là bảng dữ liệu bạn đang tìm kiếm. Không có logic KHÔNG có sẵn, bạn phải tự viết mã. Về lắp ráp - không
Tôi bối rối về mối quan hệ giữa bộ xử lý Java XSLT có trong Oracle XDK và bộ xử lý XSLT được nhúng trong Oracle DB và được sử dụng bởi hàm SQL XMLtransform. Đây là những con thú giống nhau
Tôi đang dùng thử Camel và nhận thấy đây là một công cụ hữu ích để tích hợp điểm cuối. Tôi đã thiết lập ứng dụng thử nghiệm sau: Điểm cuối đầu tiên là một yêu cầu http-get đơn giản (sử dụng tính năng cuộn tròn trên dòng lệnh). Điều này cũng giống như sử dụng công tắc trung tâm của Jetty
Tôi đang sử dụng Apache Camel và Spring Boot cho một ứng dụng. Tôi cần đọc dữ liệu từ một thư mục, sau đó giải mã xml đã đọc, sau đó xử lý đối tượng được giải mã để đặt thêm dữ liệu vào đó, sau đó mã hóa lại và gửi đến
Tôi đã biết cách viết một bộ xử lý tùy chỉnh (mở rộng org.apache.nifi.processor.AbstractProcessor). Tôi đã sử dụng kỹ thuật này và việc tạo một org.apache.ni tùy chỉnh cũng rất dễ dàng
Có bộ xử lý/phân tích cú pháp EasyList nào được viết bằng python không? http://easylist.adblockplus.org/en/ Đã tìm thấy câu trả lời hay nhất! Giống như một tháng sau :( http://adb
Tôi có một sự phát triển không thể cài đặt bất cứ thứ gì (câu chuyện dài). Tôi chỉ cần phát triển bằng HTML/JS trình duyệt thuần túy và tôi muốn sử dụng bộ tiền xử lý CSS. Tôi thích SCSS (SASS) nhưng để sử dụng được tôi phải cài đặt ru trên máy của mình
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
Đối với người mới, bạn nên bắt đầu trực tiếp từ bảng dữ liệu và hướng dẫn sử dụng của bộ xử lý ARM hay trước tiên bạn nên hiểu thế giới ARM rồi mới tiếp tục? Câu trả lời hay nhất Khi tôi bắt đầu làm việc với một công nghệ mới (đối với tôi), trước tiên tôi tìm càng nhiều bảng dữ liệu và ghi chú ứng dụng càng tốt, sau đó trực tiếp
Tôi sử dụng bộ xử lý AMD FX X6 6300. (Nó hỗ trợ ảo hóa, BIOS của tôi được đặt thành BẬT) Tôi đã cài đặt "Trình tăng tốc giả lập Intel x86". Khi tôi cố chạy thiết lập bộ tăng tốc Intel, tôi nhận được Không thể cài đặt thiết lập
Tôi là một lập trình viên xuất sắc, rất giỏi!