]> xenbits.xensource.com Git - qemu-xen.git/commitdiff
i386: hvf: fix licensing issues; isolate task handling code (GPL v2-only)
authorSergio Andres Gomez Del Real <sergio.g.delreal@gmail.com>
Wed, 13 Sep 2017 09:05:11 +0000 (04:05 -0500)
committerPaolo Bonzini <pbonzini@redhat.com>
Fri, 22 Dec 2017 14:01:46 +0000 (15:01 +0100)
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, and the corresponding compilation rule is added to
target/i386/hvf-utils/Makefile.objs.

Signed-off-by: Sergio Andres Gomez Del Real <Sergio.G.DelReal@gmail.com>
Message-Id: <20170913090522.4022-4-Sergio.G.DelReal@gmail.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
18 files changed:
target/i386/hvf-all.c
target/i386/hvf-utils/Makefile.objs
target/i386/hvf-utils/vmx.h
target/i386/hvf-utils/x86.c
target/i386/hvf-utils/x86.h
target/i386/hvf-utils/x86_decode.c
target/i386/hvf-utils/x86_decode.h
target/i386/hvf-utils/x86_descr.c
target/i386/hvf-utils/x86_descr.h
target/i386/hvf-utils/x86_emu.c
target/i386/hvf-utils/x86_emu.h
target/i386/hvf-utils/x86_gen.h
target/i386/hvf-utils/x86_mmu.c
target/i386/hvf-utils/x86_mmu.h
target/i386/hvf-utils/x86_task.c [new file with mode: 0644]
target/i386/hvf-utils/x86_task.h [new file with mode: 0644]
target/i386/hvf-utils/x86hvf.c
target/i386/hvf-utils/x86hvf.h

index b0c87ebd9f31ec28eb435d14b637c0a3045af5a9..c0989495777eee3ecd3a820d3d1e05b3c4069dfc 100644 (file)
@@ -31,6 +31,7 @@
 #include "hvf-utils/x86_mmu.h"
 #include "hvf-utils/x86_decode.h"
 #include "hvf-utils/x86_emu.h"
+#include "hvf-utils/x86_task.h"
 #include "hvf-utils/x86hvf.h"
 
 #include <Hypervisor/hv.h>
@@ -224,160 +225,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;
index 7df219ad9cb7d716b3fcc879d1ac74528498ce2f..79d8969ca82b9de5e0a743cd9336ceb96efed250 100644 (file)
@@ -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
index d086c8d25365fea0c4fee15d56c4aaa3b4671bf0..44a5c6d554865177587077876da1abd05d05cd9a 100644 (file)
@@ -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
index 587efd54fdce6031d793456a0d9c1558e2d2408b..625ea6cac03ead710bb2cb68f13a574c2989fade 100644 (file)
@@ -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"
index d32e13d6483f1132afee86e94be4534a2502b68a..ca39d829d148cd7969f0a918e2515d2d0be4b9a8 100644 (file)
@@ -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
index 13022f2851ad57adc7d6e152e08bc7a1c87e42ad..623c05133967d102a6cbdfeee9d58994954f85e5 100644 (file)
@@ -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"
index 540e95d17dfb6efb737a593e818d1bf76f4b307c..329131360f7824f0e7b288f3b49a5d0159eb97ac 100644 (file)
@@ -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
index c3b089aaa8b3ff0699631ff3d041a07ca5528f64..0b9562818f665552d205473d073e35d1d53575f3 100644 (file)
@@ -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"
index f5e247782bb8e8ee11cab663e0175a856ec78a9d..1285dd38975301f379d84095e73148a51be14033 100644 (file)
@@ -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
index eb09e38a778c5a5ab0cb401c0ee8aa6116b0faa9..f0f68f1c308e5d655f4bab34f3837c2e7c7ad4b2 100644 (file)
@@ -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/>.
  */
 
 /////////////////////////////////////////////////////////////////////////
index e1491a09353a6d63bad038a844089b3c3177ef58..cd4acb0030d9c745cf3ad41b935e4dd67cf9ca42 100644 (file)
@@ -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__
index e4340fa24464634c8e4fff929e8bef53eb52b508..2045b0e69d2262bb5ea1aae66ebe49e96b5f0443 100644 (file)
@@ -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__
index 4bb1664104e1ef7dc56dff352c1b30fc8f8c9e0e..26e9e95b0bd1b7b9c295a4062b7c01706916c70c 100644 (file)
@@ -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"
 
index 4fce48c18f079e9726fbb2c20c4c0cf1708fee18..b786af280bb2db253f6514d62f3684406b55d862 100644 (file)
@@ -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__
diff --git a/target/i386/hvf-utils/x86_task.c b/target/i386/hvf-utils/x86_task.c
new file mode 100644 (file)
index 0000000..2806814
--- /dev/null
@@ -0,0 +1,200 @@
+// 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_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);
+}
diff --git a/target/i386/hvf-utils/x86_task.h b/target/i386/hvf-utils/x86_task.h
new file mode 100644 (file)
index 0000000..4f1b188
--- /dev/null
@@ -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
index 1d9ab08cbe10be0f5f1e849ed84e2a21d2f37971..55da8298f982a9240084edc54d50256eca8e977a 100644 (file)
@@ -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"
index daa0b75273273c7657f37bf92e3571aa5a334531..79539f7282fae0954dfed4f519b858b36d8f52bd 100644 (file)
@@ -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