@@ -5,15 +5,19 @@
// Copyright 2017 The Android Open Source Project
//
// QEMU Hypervisor.framework support
-//
-// This software is licensed under the terms of the GNU General Public
-// License version 2, as published by the Free Software Foundation, and
-// may be copied, distributed, and modified under those terms.
-//
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this program; if not, see <http://www.gnu.org/licenses/>.
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/error-report.h"
@@ -28,6 +32,7 @@
#include "hvf-utils/x86_decode.h"
#include "hvf-utils/x86_emu.h"
#include "hvf-utils/x86_cpuid.h"
+#include "hvf-utils/x86_task.h"
#include "hvf-utils/x86hvf.h"
#include <Hypervisor/hv.h>
@@ -224,160 +229,6 @@ void update_apic_tpr(CPUState *cpu)
#define VECTORING_INFO_VECTOR_MASK 0xff
-// TODO: taskswitch handling
-static void save_state_to_tss32(CPUState *cpu, struct x86_tss_segment32 *tss)
-{
- /* CR3 and ldt selector are not saved intentionally */
- tss->eip = EIP(cpu);
- tss->eflags = EFLAGS(cpu);
- tss->eax = EAX(cpu);
- tss->ecx = ECX(cpu);
- tss->edx = EDX(cpu);
- tss->ebx = EBX(cpu);
- tss->esp = ESP(cpu);
- tss->ebp = EBP(cpu);
- tss->esi = ESI(cpu);
- tss->edi = EDI(cpu);
-
- tss->es = vmx_read_segment_selector(cpu, REG_SEG_ES).sel;
- tss->cs = vmx_read_segment_selector(cpu, REG_SEG_CS).sel;
- tss->ss = vmx_read_segment_selector(cpu, REG_SEG_SS).sel;
- tss->ds = vmx_read_segment_selector(cpu, REG_SEG_DS).sel;
- tss->fs = vmx_read_segment_selector(cpu, REG_SEG_FS).sel;
- tss->gs = vmx_read_segment_selector(cpu, REG_SEG_GS).sel;
-}
-
-static void load_state_from_tss32(CPUState *cpu, struct x86_tss_segment32 *tss)
-{
- wvmcs(cpu->hvf_fd, VMCS_GUEST_CR3, tss->cr3);
-
- RIP(cpu) = tss->eip;
- EFLAGS(cpu) = tss->eflags | 2;
-
- /* General purpose registers */
- RAX(cpu) = tss->eax;
- RCX(cpu) = tss->ecx;
- RDX(cpu) = tss->edx;
- RBX(cpu) = tss->ebx;
- RSP(cpu) = tss->esp;
- RBP(cpu) = tss->ebp;
- RSI(cpu) = tss->esi;
- RDI(cpu) = tss->edi;
-
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->ldt}}, REG_SEG_LDTR);
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->es}}, REG_SEG_ES);
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->cs}}, REG_SEG_CS);
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->ss}}, REG_SEG_SS);
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->ds}}, REG_SEG_DS);
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->fs}}, REG_SEG_FS);
- vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->gs}}, REG_SEG_GS);
-
-#if 0
- load_segment(cpu, REG_SEG_LDTR, tss->ldt);
- load_segment(cpu, REG_SEG_ES, tss->es);
- load_segment(cpu, REG_SEG_CS, tss->cs);
- load_segment(cpu, REG_SEG_SS, tss->ss);
- load_segment(cpu, REG_SEG_DS, tss->ds);
- load_segment(cpu, REG_SEG_FS, tss->fs);
- load_segment(cpu, REG_SEG_GS, tss->gs);
-#endif
-}
-
-static int task_switch_32(CPUState *cpu, x68_segment_selector tss_sel, x68_segment_selector old_tss_sel,
- uint64_t old_tss_base, struct x86_segment_descriptor *new_desc)
-{
- struct x86_tss_segment32 tss_seg;
- uint32_t new_tss_base = x86_segment_base(new_desc);
- uint32_t eip_offset = offsetof(struct x86_tss_segment32, eip);
- uint32_t ldt_sel_offset = offsetof(struct x86_tss_segment32, ldt);
-
- vmx_read_mem(cpu, &tss_seg, old_tss_base, sizeof(tss_seg));
- save_state_to_tss32(cpu, &tss_seg);
-
- vmx_write_mem(cpu, old_tss_base + eip_offset, &tss_seg.eip, ldt_sel_offset - eip_offset);
- vmx_read_mem(cpu, &tss_seg, new_tss_base, sizeof(tss_seg));
-
- if (old_tss_sel.sel != 0xffff) {
- tss_seg.prev_tss = old_tss_sel.sel;
-
- vmx_write_mem(cpu, new_tss_base, &tss_seg.prev_tss, sizeof(tss_seg.prev_tss));
- }
- load_state_from_tss32(cpu, &tss_seg);
- return 0;
-}
-
-static void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int reason, bool gate_valid, uint8_t gate, uint64_t gate_type)
-{
- uint64_t rip = rreg(cpu->hvf_fd, HV_X86_RIP);
- if (!gate_valid || (gate_type != VMCS_INTR_T_HWEXCEPTION &&
- gate_type != VMCS_INTR_T_HWINTR &&
- gate_type != VMCS_INTR_T_NMI)) {
- int ins_len = rvmcs(cpu->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);
- macvm_set_rip(cpu, rip + ins_len);
- return;
- }
-
- load_regs(cpu);
-
- struct x86_segment_descriptor curr_tss_desc, next_tss_desc;
- int ret;
- x68_segment_selector old_tss_sel = vmx_read_segment_selector(cpu, REG_SEG_TR);
- uint64_t old_tss_base = vmx_read_segment_base(cpu, REG_SEG_TR);
- uint32_t desc_limit;
- struct x86_call_gate task_gate_desc;
- struct vmx_segment vmx_seg;
-
- x86_read_segment_descriptor(cpu, &next_tss_desc, tss_sel);
- x86_read_segment_descriptor(cpu, &curr_tss_desc, old_tss_sel);
-
- if (reason == TSR_IDT_GATE && gate_valid) {
- int dpl;
-
- ret = x86_read_call_gate(cpu, &task_gate_desc, gate);
-
- dpl = task_gate_desc.dpl;
- x68_segment_selector cs = vmx_read_segment_selector(cpu, REG_SEG_CS);
- if (tss_sel.rpl > dpl || cs.rpl > dpl)
- ;//DPRINTF("emulate_gp");
- }
-
- desc_limit = x86_segment_limit(&next_tss_desc);
- if (!next_tss_desc.p || ((desc_limit < 0x67 && (next_tss_desc.type & 8)) || desc_limit < 0x2b)) {
- VM_PANIC("emulate_ts");
- }
-
- if (reason == TSR_IRET || reason == TSR_JMP) {
- curr_tss_desc.type &= ~(1 << 1); /* clear busy flag */
- x86_write_segment_descriptor(cpu, &curr_tss_desc, old_tss_sel);
- }
-
- if (reason == TSR_IRET)
- EFLAGS(cpu) &= ~RFLAGS_NT;
-
- if (reason != TSR_CALL && reason != TSR_IDT_GATE)
- old_tss_sel.sel = 0xffff;
-
- if (reason != TSR_IRET) {
- next_tss_desc.type |= (1 << 1); /* set busy flag */
- x86_write_segment_descriptor(cpu, &next_tss_desc, tss_sel);
- }
-
- if (next_tss_desc.type & 8)
- ret = task_switch_32(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
- else
- //ret = task_switch_16(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
- VM_PANIC("task_switch_16");
-
- macvm_set_cr0(cpu->hvf_fd, rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0) | CR0_TS);
- x86_segment_descriptor_to_vmx(cpu, tss_sel, &next_tss_desc, &vmx_seg);
- vmx_write_segment_descriptor(cpu, &vmx_seg, REG_SEG_TR);
-
- store_regs(cpu);
-
- hv_vcpu_invalidate_tlb(cpu->hvf_fd);
- hv_vcpu_flush(cpu->hvf_fd);
-}
-
static void hvf_handle_interrupt(CPUState * cpu, int mask)
{
cpu->interrupt_request |= mask;
@@ -1 +1 @@
-obj-y += x86.o x86_cpuid.o x86_decode.o x86_descr.o x86_emu.o x86_flags.o x86_mmu.o x86hvf.o
+obj-y += x86.o x86_cpuid.o x86_decode.o x86_descr.o x86_emu.o x86_flags.o x86_mmu.o x86hvf.o x86_task.o
@@ -6,17 +6,17 @@
* Interfaces to Hypervisor.framework to read/write X86 registers and VMCS.
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VMX_H
@@ -3,17 +3,17 @@
* Copyright (C) 2017 Google Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
@@ -3,17 +3,17 @@
* Copyright (C) 2017 Veertu Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
@@ -4,18 +4,18 @@
* Copyright (c) 2003 Fabrice Bellard
* Copyright (c) 2017 Google Inc.
*
- * This library is free software; you can redistribute it and/or
+ * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
- * This library is distributed in the hope that it will be useful,
+ * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*
* cpuid
*/
@@ -2,17 +2,17 @@
* Copyright (C) 2016 Veertu Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CPUID_H__
#define __CPUID_H__
@@ -3,17 +3,17 @@
* Copyright (C) 2017 Google Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
@@ -2,17 +2,17 @@
* Copyright (C) 2016 Veertu Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
@@ -3,17 +3,17 @@
* Copyright (C) 2017 Google Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
@@ -3,17 +3,17 @@
* Copyright (C) 2017 Google Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
@@ -3,17 +3,17 @@
* Copyright (C) 2017 Google Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/////////////////////////////////////////////////////////////////////////
@@ -3,17 +3,17 @@
* Copyright (C) 2017 Google Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __X86_EMU_H__
#define __X86_EMU_H__
@@ -3,17 +3,17 @@
* Copyright (C) 2017 Google Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __X86_GEN_H__
#define __X86_GEN_H__
@@ -3,17 +3,17 @@
* Copyright (C) 2017 Google Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
@@ -3,17 +3,17 @@
* Copyright (C) 2017 Google Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __X86_MMU_H__
#define __X86_MMU_H__
new file mode 100644
@@ -0,0 +1,201 @@
+// This software is licensed under the terms of the GNU General Public
+// License version 2, as published by the Free Software Foundation, and
+// may be copied, distributed, and modified under those terms.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+
+#include "sysemu/hvf.h"
+#include "hvf-i386.h"
+#include "hvf-utils/vmcs.h"
+#include "hvf-utils/vmx.h"
+#include "hvf-utils/x86.h"
+#include "hvf-utils/x86_descr.h"
+#include "hvf-utils/x86_mmu.h"
+#include "hvf-utils/x86_decode.h"
+#include "hvf-utils/x86_emu.h"
+#include "hvf-utils/x86_cpuid.h"
+#include "hvf-utils/x86_task.h"
+#include "hvf-utils/x86hvf.h"
+
+#include <Hypervisor/hv.h>
+#include <Hypervisor/hv_vmx.h>
+
+#include "exec/address-spaces.h"
+#include "exec/exec-all.h"
+#include "exec/ioport.h"
+#include "hw/i386/apic_internal.h"
+#include "hw/boards.h"
+#include "qemu/main-loop.h"
+#include "strings.h"
+#include "sysemu/accel.h"
+#include "sysemu/sysemu.h"
+#include "target/i386/cpu.h"
+
+// TODO: taskswitch handling
+static void save_state_to_tss32(CPUState *cpu, struct x86_tss_segment32 *tss)
+{
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ CPUX86State *env = &x86_cpu->env;
+
+ /* CR3 and ldt selector are not saved intentionally */
+ tss->eip = EIP(env);
+ tss->eflags = EFLAGS(env);
+ tss->eax = EAX(env);
+ tss->ecx = ECX(env);
+ tss->edx = EDX(env);
+ tss->ebx = EBX(env);
+ tss->esp = ESP(env);
+ tss->ebp = EBP(env);
+ tss->esi = ESI(env);
+ tss->edi = EDI(env);
+
+ tss->es = vmx_read_segment_selector(cpu, REG_SEG_ES).sel;
+ tss->cs = vmx_read_segment_selector(cpu, REG_SEG_CS).sel;
+ tss->ss = vmx_read_segment_selector(cpu, REG_SEG_SS).sel;
+ tss->ds = vmx_read_segment_selector(cpu, REG_SEG_DS).sel;
+ tss->fs = vmx_read_segment_selector(cpu, REG_SEG_FS).sel;
+ tss->gs = vmx_read_segment_selector(cpu, REG_SEG_GS).sel;
+}
+
+static void load_state_from_tss32(CPUState *cpu, struct x86_tss_segment32 *tss)
+{
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ CPUX86State *env = &x86_cpu->env;
+
+ wvmcs(cpu->hvf_fd, VMCS_GUEST_CR3, tss->cr3);
+
+ RIP(env) = tss->eip;
+ EFLAGS(env) = tss->eflags | 2;
+
+ /* General purpose registers */
+ RAX(env) = tss->eax;
+ RCX(env) = tss->ecx;
+ RDX(env) = tss->edx;
+ RBX(env) = tss->ebx;
+ RSP(env) = tss->esp;
+ RBP(env) = tss->ebp;
+ RSI(env) = tss->esi;
+ RDI(env) = tss->edi;
+
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->ldt}}, REG_SEG_LDTR);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->es}}, REG_SEG_ES);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->cs}}, REG_SEG_CS);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->ss}}, REG_SEG_SS);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->ds}}, REG_SEG_DS);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->fs}}, REG_SEG_FS);
+ vmx_write_segment_selector(cpu, (x68_segment_selector){{tss->gs}}, REG_SEG_GS);
+
+#if 0
+ load_segment(cpu, REG_SEG_LDTR, tss->ldt);
+ load_segment(cpu, REG_SEG_ES, tss->es);
+ load_segment(cpu, REG_SEG_CS, tss->cs);
+ load_segment(cpu, REG_SEG_SS, tss->ss);
+ load_segment(cpu, REG_SEG_DS, tss->ds);
+ load_segment(cpu, REG_SEG_FS, tss->fs);
+ load_segment(cpu, REG_SEG_GS, tss->gs);
+#endif
+}
+
+static int task_switch_32(CPUState *cpu, x68_segment_selector tss_sel, x68_segment_selector old_tss_sel,
+ uint64_t old_tss_base, struct x86_segment_descriptor *new_desc)
+{
+ struct x86_tss_segment32 tss_seg;
+ uint32_t new_tss_base = x86_segment_base(new_desc);
+ uint32_t eip_offset = offsetof(struct x86_tss_segment32, eip);
+ uint32_t ldt_sel_offset = offsetof(struct x86_tss_segment32, ldt);
+
+ vmx_read_mem(cpu, &tss_seg, old_tss_base, sizeof(tss_seg));
+ save_state_to_tss32(cpu, &tss_seg);
+
+ vmx_write_mem(cpu, old_tss_base + eip_offset, &tss_seg.eip, ldt_sel_offset - eip_offset);
+ vmx_read_mem(cpu, &tss_seg, new_tss_base, sizeof(tss_seg));
+
+ if (old_tss_sel.sel != 0xffff) {
+ tss_seg.prev_tss = old_tss_sel.sel;
+
+ vmx_write_mem(cpu, new_tss_base, &tss_seg.prev_tss, sizeof(tss_seg.prev_tss));
+ }
+ load_state_from_tss32(cpu, &tss_seg);
+ return 0;
+}
+
+void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel, int reason, bool gate_valid, uint8_t gate, uint64_t gate_type)
+{
+ uint64_t rip = rreg(cpu->hvf_fd, HV_X86_RIP);
+ if (!gate_valid || (gate_type != VMCS_INTR_T_HWEXCEPTION &&
+ gate_type != VMCS_INTR_T_HWINTR &&
+ gate_type != VMCS_INTR_T_NMI)) {
+ int ins_len = rvmcs(cpu->hvf_fd, VMCS_EXIT_INSTRUCTION_LENGTH);
+ macvm_set_rip(cpu, rip + ins_len);
+ return;
+ }
+
+ load_regs(cpu);
+
+ struct x86_segment_descriptor curr_tss_desc, next_tss_desc;
+ int ret;
+ x68_segment_selector old_tss_sel = vmx_read_segment_selector(cpu, REG_SEG_TR);
+ uint64_t old_tss_base = vmx_read_segment_base(cpu, REG_SEG_TR);
+ uint32_t desc_limit;
+ struct x86_call_gate task_gate_desc;
+ struct vmx_segment vmx_seg;
+
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ CPUX86State *env = &x86_cpu->env;
+
+ x86_read_segment_descriptor(cpu, &next_tss_desc, tss_sel);
+ x86_read_segment_descriptor(cpu, &curr_tss_desc, old_tss_sel);
+
+ if (reason == TSR_IDT_GATE && gate_valid) {
+ int dpl;
+
+ ret = x86_read_call_gate(cpu, &task_gate_desc, gate);
+
+ dpl = task_gate_desc.dpl;
+ x68_segment_selector cs = vmx_read_segment_selector(cpu, REG_SEG_CS);
+ if (tss_sel.rpl > dpl || cs.rpl > dpl)
+ ;//DPRINTF("emulate_gp");
+ }
+
+ desc_limit = x86_segment_limit(&next_tss_desc);
+ if (!next_tss_desc.p || ((desc_limit < 0x67 && (next_tss_desc.type & 8)) || desc_limit < 0x2b)) {
+ VM_PANIC("emulate_ts");
+ }
+
+ if (reason == TSR_IRET || reason == TSR_JMP) {
+ curr_tss_desc.type &= ~(1 << 1); /* clear busy flag */
+ x86_write_segment_descriptor(cpu, &curr_tss_desc, old_tss_sel);
+ }
+
+ if (reason == TSR_IRET)
+ EFLAGS(env) &= ~RFLAGS_NT;
+
+ if (reason != TSR_CALL && reason != TSR_IDT_GATE)
+ old_tss_sel.sel = 0xffff;
+
+ if (reason != TSR_IRET) {
+ next_tss_desc.type |= (1 << 1); /* set busy flag */
+ x86_write_segment_descriptor(cpu, &next_tss_desc, tss_sel);
+ }
+
+ if (next_tss_desc.type & 8)
+ ret = task_switch_32(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
+ else
+ //ret = task_switch_16(cpu, tss_sel, old_tss_sel, old_tss_base, &next_tss_desc);
+ VM_PANIC("task_switch_16");
+
+ macvm_set_cr0(cpu->hvf_fd, rvmcs(cpu->hvf_fd, VMCS_GUEST_CR0) | CR0_TS);
+ x86_segment_descriptor_to_vmx(cpu, tss_sel, &next_tss_desc, &vmx_seg);
+ vmx_write_segment_descriptor(cpu, &vmx_seg, REG_SEG_TR);
+
+ store_regs(cpu);
+
+ hv_vcpu_invalidate_tlb(cpu->hvf_fd);
+ hv_vcpu_flush(cpu->hvf_fd);
+}
new file mode 100644
@@ -0,0 +1,18 @@
+/* This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef HVF_TASK
+#define HVF_TASK
+void vmx_handle_task_switch(CPUState *cpu, x68_segment_selector tss_sel,
+ int reason, bool gate_valid, uint8_t gate, uint64_t gate_type);
+#endif
@@ -4,17 +4,17 @@
* Copyright (C) 2017 Google Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
@@ -3,17 +3,17 @@
* Copyright (C) 2017 Google Inc,
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 or
- * (at your option) version 3 of the License.
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef X86HVF_H
#define X86HVF_H
This patch replaces the license header for those files that were either GPL v2-or-v3, or GPL v2-only; the replacing license is GPL v2-or-later. The code for task switching/handling, which is derived from KVM and hence is GPL v2-only, is isolated in the new files (with this license) x86_task.c/.h Signed-off-by: Sergio Andres Gomez Del Real <Sergio.G.DelReal@gmail.com> --- target/i386/hvf-all.c | 173 +++---------------------------- target/i386/hvf-utils/Makefile.objs | 2 +- target/i386/hvf-utils/vmx.h | 14 +-- target/i386/hvf-utils/x86.c | 14 +-- target/i386/hvf-utils/x86.h | 14 +-- target/i386/hvf-utils/x86_cpuid.c | 6 +- target/i386/hvf-utils/x86_cpuid.h | 14 +-- target/i386/hvf-utils/x86_decode.c | 14 +-- target/i386/hvf-utils/x86_decode.h | 14 +-- target/i386/hvf-utils/x86_descr.c | 14 +-- target/i386/hvf-utils/x86_descr.h | 14 +-- target/i386/hvf-utils/x86_emu.c | 14 +-- target/i386/hvf-utils/x86_emu.h | 14 +-- target/i386/hvf-utils/x86_gen.h | 14 +-- target/i386/hvf-utils/x86_mmu.c | 14 +-- target/i386/hvf-utils/x86_mmu.h | 14 +-- target/i386/hvf-utils/x86_task.c | 201 ++++++++++++++++++++++++++++++++++++ target/i386/hvf-utils/x86_task.h | 18 ++++ target/i386/hvf-utils/x86hvf.c | 14 +-- target/i386/hvf-utils/x86hvf.h | 14 +-- 20 files changed, 340 insertions(+), 270 deletions(-) create mode 100644 target/i386/hvf-utils/x86_task.c create mode 100644 target/i386/hvf-utils/x86_task.h