Deleted Added
full compact
vmx.c (249450) vmx.c (249879)
1/*-
2 * Copyright (c) 2011 NetApp, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 2011 NetApp, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/amd64/vmm/intel/vmx.c 249450 2013-04-13 21:41:51Z neel $
26 * $FreeBSD: head/sys/amd64/vmm/intel/vmx.c 249879 2013-04-25 04:56:43Z grehan $
27 */
28
29#include <sys/cdefs.h>
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmx.c 249450 2013-04-13 21:41:51Z neel $");
30__FBSDID("$FreeBSD: head/sys/amd64/vmm/intel/vmx.c 249879 2013-04-25 04:56:43Z grehan $");
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/smp.h>
35#include <sys/kernel.h>
36#include <sys/malloc.h>
37#include <sys/pcpu.h>
38#include <sys/proc.h>

--- 623 unchanged lines hidden (view full) ---

662 shadow_value = cr0_ones_mask;
663 } else {
664 mask_ident = VMCS_CR4_MASK;
665 mask_value = cr4_ones_mask | cr4_zeros_mask;
666 shadow_ident = VMCS_CR4_SHADOW;
667 shadow_value = cr4_ones_mask;
668 }
669
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/smp.h>
35#include <sys/kernel.h>
36#include <sys/malloc.h>
37#include <sys/pcpu.h>
38#include <sys/proc.h>

--- 623 unchanged lines hidden (view full) ---

662 shadow_value = cr0_ones_mask;
663 } else {
664 mask_ident = VMCS_CR4_MASK;
665 mask_value = cr4_ones_mask | cr4_zeros_mask;
666 shadow_ident = VMCS_CR4_SHADOW;
667 shadow_value = cr4_ones_mask;
668 }
669
670 error = vmcs_setreg(vmcs, VMCS_IDENT(mask_ident), mask_value);
670 error = vmcs_setreg(vmcs, 0, VMCS_IDENT(mask_ident), mask_value);
671 if (error)
672 return (error);
673
671 if (error)
672 return (error);
673
674 error = vmcs_setreg(vmcs, VMCS_IDENT(shadow_ident), shadow_value);
674 error = vmcs_setreg(vmcs, 0, VMCS_IDENT(shadow_ident), shadow_value);
675 if (error)
676 return (error);
677
678 return (0);
679}
680#define vmx_setup_cr0_shadow(vmcs) vmx_setup_cr_shadow(0, (vmcs))
681#define vmx_setup_cr4_shadow(vmcs) vmx_setup_cr_shadow(4, (vmcs))
682

--- 929 unchanged lines hidden (view full) ---

1612 return (0);
1613 } else
1614 return (EINVAL);
1615}
1616
1617static int
1618vmx_getreg(void *arg, int vcpu, int reg, uint64_t *retval)
1619{
675 if (error)
676 return (error);
677
678 return (0);
679}
680#define vmx_setup_cr0_shadow(vmcs) vmx_setup_cr_shadow(0, (vmcs))
681#define vmx_setup_cr4_shadow(vmcs) vmx_setup_cr_shadow(4, (vmcs))
682

--- 929 unchanged lines hidden (view full) ---

1612 return (0);
1613 } else
1614 return (EINVAL);
1615}
1616
1617static int
1618vmx_getreg(void *arg, int vcpu, int reg, uint64_t *retval)
1619{
1620 int running, hostcpu;
1620 struct vmx *vmx = arg;
1621
1621 struct vmx *vmx = arg;
1622
1623 running = vcpu_is_running(vmx->vm, vcpu, &hostcpu);
1624 if (running && hostcpu != curcpu)
1625 panic("vmx_getreg: %s%d is running", vm_name(vmx->vm), vcpu);
1626
1622 if (vmxctx_getreg(&vmx->ctx[vcpu], reg, retval) == 0)
1623 return (0);
1624
1627 if (vmxctx_getreg(&vmx->ctx[vcpu], reg, retval) == 0)
1628 return (0);
1629
1625 /*
1626 * If the vcpu is running then don't mess with the VMCS.
1627 *
1628 * vmcs_getreg will VMCLEAR the vmcs when it is done which will cause
1629 * the subsequent vmlaunch/vmresume to fail.
1630 */
1631 if (vcpu_is_running(vmx->vm, vcpu))
1632 panic("vmx_getreg: %s%d is running", vm_name(vmx->vm), vcpu);
1633
1634 return (vmcs_getreg(&vmx->vmcs[vcpu], reg, retval));
1630 return (vmcs_getreg(&vmx->vmcs[vcpu], running, reg, retval));
1635}
1636
1637static int
1638vmx_setreg(void *arg, int vcpu, int reg, uint64_t val)
1639{
1631}
1632
1633static int
1634vmx_setreg(void *arg, int vcpu, int reg, uint64_t val)
1635{
1640 int error;
1636 int error, hostcpu, running;
1641 uint64_t ctls;
1642 struct vmx *vmx = arg;
1643
1637 uint64_t ctls;
1638 struct vmx *vmx = arg;
1639
1644 /*
1645 * XXX Allow caller to set contents of the guest registers saved in
1646 * the 'vmxctx' even though the vcpu might be running. We need this
1647 * specifically to support the rdmsr emulation that will set the
1648 * %eax and %edx registers during vm exit processing.
1649 */
1640 running = vcpu_is_running(vmx->vm, vcpu, &hostcpu);
1641 if (running && hostcpu != curcpu)
1642 panic("vmx_setreg: %s%d is running", vm_name(vmx->vm), vcpu);
1643
1650 if (vmxctx_setreg(&vmx->ctx[vcpu], reg, val) == 0)
1651 return (0);
1652
1644 if (vmxctx_setreg(&vmx->ctx[vcpu], reg, val) == 0)
1645 return (0);
1646
1653 /*
1654 * If the vcpu is running then don't mess with the VMCS.
1655 *
1656 * vmcs_setreg will VMCLEAR the vmcs when it is done which will cause
1657 * the subsequent vmlaunch/vmresume to fail.
1658 */
1659 if (vcpu_is_running(vmx->vm, vcpu))
1660 panic("vmx_setreg: %s%d is running", vm_name(vmx->vm), vcpu);
1647 error = vmcs_setreg(&vmx->vmcs[vcpu], running, reg, val);
1661
1648
1662 error = vmcs_setreg(&vmx->vmcs[vcpu], reg, val);
1663
1664 if (error == 0) {
1665 /*
1666 * If the "load EFER" VM-entry control is 1 then the
1667 * value of EFER.LMA must be identical to "IA-32e mode guest"
1668 * bit in the VM-entry control.
1669 */
1670 if ((entry_ctls & VM_ENTRY_LOAD_EFER) != 0 &&
1671 (reg == VM_REG_GUEST_EFER)) {
1649 if (error == 0) {
1650 /*
1651 * If the "load EFER" VM-entry control is 1 then the
1652 * value of EFER.LMA must be identical to "IA-32e mode guest"
1653 * bit in the VM-entry control.
1654 */
1655 if ((entry_ctls & VM_ENTRY_LOAD_EFER) != 0 &&
1656 (reg == VM_REG_GUEST_EFER)) {
1672 vmcs_getreg(&vmx->vmcs[vcpu],
1657 vmcs_getreg(&vmx->vmcs[vcpu], running,
1673 VMCS_IDENT(VMCS_ENTRY_CTLS), &ctls);
1674 if (val & EFER_LMA)
1675 ctls |= VM_ENTRY_GUEST_LMA;
1676 else
1677 ctls &= ~VM_ENTRY_GUEST_LMA;
1658 VMCS_IDENT(VMCS_ENTRY_CTLS), &ctls);
1659 if (val & EFER_LMA)
1660 ctls |= VM_ENTRY_GUEST_LMA;
1661 else
1662 ctls &= ~VM_ENTRY_GUEST_LMA;
1678 vmcs_setreg(&vmx->vmcs[vcpu],
1663 vmcs_setreg(&vmx->vmcs[vcpu], running,
1679 VMCS_IDENT(VMCS_ENTRY_CTLS), ctls);
1680 }
1681 }
1682
1683 return (error);
1684}
1685
1686static int

--- 30 unchanged lines hidden (view full) ---

1717 0x5, /* VM_PRIV_SW_EXCEPTION */
1718 0x6, /* VM_SW_EXCEPTION */
1719 };
1720
1721 /*
1722 * If there is already an exception pending to be delivered to the
1723 * vcpu then just return.
1724 */
1664 VMCS_IDENT(VMCS_ENTRY_CTLS), ctls);
1665 }
1666 }
1667
1668 return (error);
1669}
1670
1671static int

--- 30 unchanged lines hidden (view full) ---

1702 0x5, /* VM_PRIV_SW_EXCEPTION */
1703 0x6, /* VM_SW_EXCEPTION */
1704 };
1705
1706 /*
1707 * If there is already an exception pending to be delivered to the
1708 * vcpu then just return.
1709 */
1725 error = vmcs_getreg(vmcs, VMCS_IDENT(VMCS_ENTRY_INTR_INFO), &info);
1710 error = vmcs_getreg(vmcs, 0, VMCS_IDENT(VMCS_ENTRY_INTR_INFO), &info);
1726 if (error)
1727 return (error);
1728
1729 if (info & VMCS_INTERRUPTION_INFO_VALID)
1730 return (EAGAIN);
1731
1732 info = vector | (type_map[type] << 8) | (code_valid ? 1 << 11 : 0);
1733 info |= VMCS_INTERRUPTION_INFO_VALID;
1711 if (error)
1712 return (error);
1713
1714 if (info & VMCS_INTERRUPTION_INFO_VALID)
1715 return (EAGAIN);
1716
1717 info = vector | (type_map[type] << 8) | (code_valid ? 1 << 11 : 0);
1718 info |= VMCS_INTERRUPTION_INFO_VALID;
1734 error = vmcs_setreg(vmcs, VMCS_IDENT(VMCS_ENTRY_INTR_INFO), info);
1719 error = vmcs_setreg(vmcs, 0, VMCS_IDENT(VMCS_ENTRY_INTR_INFO), info);
1735 if (error != 0)
1736 return (error);
1737
1738 if (code_valid) {
1720 if (error != 0)
1721 return (error);
1722
1723 if (code_valid) {
1739 error = vmcs_setreg(vmcs,
1724 error = vmcs_setreg(vmcs, 0,
1740 VMCS_IDENT(VMCS_ENTRY_EXCEPTION_ERROR),
1741 code);
1742 }
1743 return (error);
1744}
1745
1746static int
1747vmx_getcap(void *arg, int vcpu, int type, int *retval)

--- 139 unchanged lines hidden ---
1725 VMCS_IDENT(VMCS_ENTRY_EXCEPTION_ERROR),
1726 code);
1727 }
1728 return (error);
1729}
1730
1731static int
1732vmx_getcap(void *arg, int vcpu, int type, int *retval)

--- 139 unchanged lines hidden ---