diff options
| author | Alexey Kardashevskiy <aik@linux.ibm.com> | 2020-11-19 21:01:35 +1100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2020-11-20 15:31:42 +0100 |
| commit | 680688040fc26d17a49a9663fbbd6a716c6247b6 (patch) | |
| tree | 4cb0e538575460b72864d2e782a77371aa7ec173 /pkg/csource/generated.go | |
| parent | e72f8f11e096d36aefc41a35c718dced97c45dea (diff) | |
pkg/ifuzz/powerpc: add powerpc support
This adds KVM's syz_kvm_setup_cpu pseudo syscall. This adds placeholder
for options (none implemented yet).
This adds instruction generator for ifuzz; this also adds a few pseudo
instructions to simulate super/hyper/ultracalls
(a PPC64/pseries platform thing).
The insns.go is generated from PowerISA_public.v3.0B.pdf [1] by
a horrendous python3 script on top of pdftotext. The ISA covers POWER9
which is the latest available POWER CPU at the moment. The next ISA
for POWER10 is quite different and we will deal with it later.
The // comment after every instruction is a fixed opcode list for
verification purposes.
This does not define DecodeExt as there is no obvious replacement of
the Intel XED library for POWERPC (gapstone-capstone, later, may be).
[1] https://openpowerfoundation.org/?resource_lib=power-isa-version-3-0
Signed-off-by: Alexey Kardashevskiy <aik@linux.ibm.com>
Diffstat (limited to 'pkg/csource/generated.go')
| -rw-r--r-- | pkg/csource/generated.go | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index 75f228a7f..5e234d47a 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -7180,6 +7180,144 @@ static long syz_kvm_setup_cpu(volatile long a0, volatile long a1, volatile long return 0; } +#elif GOARCH_ppc64 || GOARCH_ppc64le + +#define ADDR_TEXT 0x0000 +#define ADDR_GDT 0x1000 +#define ADDR_LDT 0x1800 +#define ADDR_PML4 0x2000 +#define ADDR_PDP 0x3000 +#define ADDR_PD 0x4000 +#define ADDR_STACK0 0x0f80 +#define ADDR_VAR_HLT 0x2800 +#define ADDR_VAR_SYSRET 0x2808 +#define ADDR_VAR_SYSEXIT 0x2810 +#define ADDR_VAR_IDT 0x3800 +#define ADDR_VAR_TSS64 0x3a00 +#define ADDR_VAR_TSS64_CPL3 0x3c00 +#define ADDR_VAR_TSS16 0x3d00 +#define ADDR_VAR_TSS16_2 0x3e00 +#define ADDR_VAR_TSS16_CPL3 0x3f00 +#define ADDR_VAR_TSS32 0x4800 +#define ADDR_VAR_TSS32_2 0x4a00 +#define ADDR_VAR_TSS32_CPL3 0x4c00 +#define ADDR_VAR_TSS32_VM86 0x4e00 +#define ADDR_VAR_VMXON_PTR 0x5f00 +#define ADDR_VAR_VMCS_PTR 0x5f08 +#define ADDR_VAR_VMEXIT_PTR 0x5f10 +#define ADDR_VAR_VMWRITE_FLD 0x5f18 +#define ADDR_VAR_VMWRITE_VAL 0x5f20 +#define ADDR_VAR_VMXON 0x6000 +#define ADDR_VAR_VMCS 0x7000 +#define ADDR_VAR_VMEXIT_CODE 0x9000 +#define ADDR_VAR_USER_CODE 0x9100 +#define ADDR_VAR_USER_CODE2 0x9120 + +#define SEL_LDT (1 << 3) +#define SEL_CS16 (2 << 3) +#define SEL_DS16 (3 << 3) +#define SEL_CS16_CPL3 ((4 << 3) + 3) +#define SEL_DS16_CPL3 ((5 << 3) + 3) +#define SEL_CS32 (6 << 3) +#define SEL_DS32 (7 << 3) +#define SEL_CS32_CPL3 ((8 << 3) + 3) +#define SEL_DS32_CPL3 ((9 << 3) + 3) +#define SEL_CS64 (10 << 3) +#define SEL_DS64 (11 << 3) +#define SEL_CS64_CPL3 ((12 << 3) + 3) +#define SEL_DS64_CPL3 ((13 << 3) + 3) +#define SEL_CGATE16 (14 << 3) +#define SEL_TGATE16 (15 << 3) +#define SEL_CGATE32 (16 << 3) +#define SEL_TGATE32 (17 << 3) +#define SEL_CGATE64 (18 << 3) +#define SEL_CGATE64_HI (19 << 3) +#define SEL_TSS16 (20 << 3) +#define SEL_TSS16_2 (21 << 3) +#define SEL_TSS16_CPL3 ((22 << 3) + 3) +#define SEL_TSS32 (23 << 3) +#define SEL_TSS32_2 (24 << 3) +#define SEL_TSS32_CPL3 ((25 << 3) + 3) +#define SEL_TSS32_VM86 (26 << 3) +#define SEL_TSS64 (27 << 3) +#define SEL_TSS64_HI (28 << 3) +#define SEL_TSS64_CPL3 ((29 << 3) + 3) +#define SEL_TSS64_CPL3_HI (30 << 3) + +#define MSR_IA32_FEATURE_CONTROL 0x3a +#define MSR_IA32_VMX_BASIC 0x480 +#define MSR_IA32_SMBASE 0x9e +#define MSR_IA32_SYSENTER_CS 0x174 +#define MSR_IA32_SYSENTER_ESP 0x175 +#define MSR_IA32_SYSENTER_EIP 0x176 +#define MSR_IA32_STAR 0xC0000081 +#define MSR_IA32_LSTAR 0xC0000082 +#define MSR_IA32_VMX_PROCBASED_CTLS2 0x48B + +#define NEXT_INSN $0xbadc0de +#define PREFIX_SIZE 0xba1d + + +struct kvm_text { + uintptr_t typ; + const void* text; + uintptr_t size; +}; +static long syz_kvm_setup_cpu(volatile long a0, volatile long a1, volatile long a2, volatile long a3, volatile long a4, volatile long a5, volatile long a6, volatile long a7) +{ + const int vmfd = a0; + const int cpufd = a1; + char* const host_mem = (char*)a2; + const struct kvm_text* const text_array_ptr = (struct kvm_text*)a3; + const uintptr_t text_count = a4; + + const uintptr_t page_size = 16 << 10; + const uintptr_t guest_mem_size = 256 << 20; + const uintptr_t guest_mem = 0; + + (void)text_count; + const void* text = 0; + uintptr_t text_size = 0; + NONFAILING(text = text_array_ptr[0].text); + NONFAILING(text_size = text_array_ptr[0].size); + + for (uintptr_t i = 0; i < guest_mem_size / page_size; i++) { + struct kvm_userspace_memory_region memreg; + memreg.slot = i; + memreg.flags = 0; + memreg.guest_phys_addr = guest_mem + i * page_size; + memreg.memory_size = page_size; + memreg.userspace_addr = (uintptr_t)host_mem + i * page_size; + ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &memreg); + } + + struct kvm_regs regs; + struct kvm_sregs sregs; + if (ioctl(cpufd, KVM_GET_SREGS, &sregs)) + return -1; + if (ioctl(cpufd, KVM_GET_REGS, ®s)) + return -1; + regs.msr = 1ULL | (1ULL << 63); + + memcpy(host_mem, text, text_size); + + if (ioctl(cpufd, KVM_SET_SREGS, &sregs)) + return -1; + if (ioctl(cpufd, KVM_SET_REGS, ®s)) + return -1; +#define MAX_HCALL 0x450 + for (unsigned hcall = 4; hcall < MAX_HCALL; hcall += 4) { + struct kvm_enable_cap cap = { + .cap = KVM_CAP_PPC_ENABLE_HCALL, + .flags = 0, + .args = {hcall, 1}, + }; + ioctl(vmfd, KVM_ENABLE_CAP, &cap); + } + + return 0; +} + #elif !GOARCH_arm static long syz_kvm_setup_cpu(volatile long a0, volatile long a1, volatile long a2, volatile long a3, volatile long a4, volatile long a5, volatile long a6, volatile long a7) { |
