[no subject]
subscribe kvm-commits -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [NetKVM] Number of handled RX packets handled during DPC are configured through INF file and advanced tab in device manager.
repository: C:/dev/kvm-guest-drivers-windows branch: master commit fac89bff95d612c656cdf6fce9f8e1597ae91f35 Author: Yan Vugenfirer yvuge...@redhat.com Date: Wed Jul 13 14:49:49 2011 +0300 [NetKVM] Number of handled RX packets handled during DPC are configured through INF file and advanced tab in device manager. diff --git a/NetKVM/Common/ParaNdis-Common.c b/NetKVM/Common/ParaNdis-Common.c index 1a51474..af66de1 100644 --- a/NetKVM/Common/ParaNdis-Common.c +++ b/NetKVM/Common/ParaNdis-Common.c @@ -111,6 +111,7 @@ typedef struct _tagConfigurationEntries tConfigurationEntry VlanId; tConfigurationEntry UseMergeableBuffers; tConfigurationEntry MTU; + tConfigurationEntry NumberOfHandledRXPackersInDPC; }tConfigurationEntries; static const tConfigurationEntries defaultConfiguration = @@ -149,6 +150,7 @@ static const tConfigurationEntries defaultConfiguration = { VlanId, 0, 0, 4095}, { MergeableBuf, 1, 0, 1}, { MTU, 1500, 500, 65500}, + { NumberOfHandledRXPackersInDPC, MAX_RX_LOOPS, 1, 1}, }; static void ParaNdis_ResetVirtIONetDevice(PARANDIS_ADAPTER *pContext) @@ -278,6 +280,7 @@ static void ReadNicConfiguration(PARANDIS_ADAPTER *pContext, PUCHAR *ppNewMACAdd GetConfigurationEntry(cfg, pConfiguration-VlanId); GetConfigurationEntry(cfg, pConfiguration-UseMergeableBuffers); GetConfigurationEntry(cfg, pConfiguration-MTU); + GetConfigurationEntry(cfg, pConfiguration-NumberOfHandledRXPackersInDPC); #if !defined(WPP_EVENT_TRACING) bDebugPrint = pConfiguration-isLogEnabled.ulValue; @@ -290,6 +293,7 @@ static void ReadNicConfiguration(PARANDIS_ADAPTER *pContext, PUCHAR *ppNewMACAdd pContext-nEnableDPCChecker = pConfiguration-dpcChecker.ulValue; pContext-bDoInterruptRecovery = pConfiguration-InterruptRecovery.ulValue != 0; pContext-Limits.nPrintDiagnostic = pConfiguration-LogStatistics.ulValue; + pContext-uNumberOfHandledRXPacketsInDPC = pConfiguration-NumberOfHandledRXPackersInDPC.ulValue; pContext-bDoHardReset = pConfiguration-HardReset.ulValue != 0; pContext-bDoSupportPriority = pConfiguration-PrioritySupport.ulValue != 0; pContext-ulFormalLinkSpeed = pConfiguration-ConnectRate.ulValue * 100; @@ -1772,7 +1776,8 @@ ULONG ParaNdis_DPCWorkBody(PARANDIS_ADAPTER *pContext) } if (interruptSources isReceive) { - int nRestartResult = 0, nLoop = 0; + int nRestartResult = 0; + UINT nLoop = 0; do { UINT n; @@ -1788,7 +1793,7 @@ ULONG ParaNdis_DPCWorkBody(PARANDIS_ADAPTER *pContext) NdisReleaseSpinLock(pContext-ReceiveLock); DPrintf(nRestartResult ? 2 : 6, ([%s] queue restarted%s, __FUNCTION__, nRestartResult ? (Rerun) : (Done))); ++nLoop; - if (nLoop MAX_RX_LOOPS) + if (nLoop pContext-uNumberOfHandledRXPacketsInDPC) { DPrintf(0, ([%s] Breaking Rx loop on %d-th operation, __FUNCTION__, nLoop)); ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)4, nRestartResult, 0, 0); diff --git a/NetKVM/wlh/netkvm.inf b/NetKVM/wlh/netkvm.inf index 8143375..752da16 100644 --- a/NetKVM/wlh/netkvm.inf +++ b/NetKVM/wlh/netkvm.inf @@ -191,6 +191,13 @@ HKR, Ndi\params\ConnectTimer, min,0, 0 HKR, Ndi\params\ConnectTimer, max,0, 30 HKR, Ndi\params\ConnectTimer, step, 0, 50 +HKR, Ndi\params\NumberOfHandledRXPackersInDPC, ParamDesc, 0, %NumberOfHandledRXPackersInDPC% +HKR, Ndi\params\NumberOfHandledRXPackersInDPC, type, 0, long +HKR, Ndi\params\NumberOfHandledRXPackersInDPC, default,0, 1000 +HKR, Ndi\params\NumberOfHandledRXPackersInDPC, min,0, 1 +HKR, Ndi\params\NumberOfHandledRXPackersInDPC, max,0, 1 +HKR, Ndi\params\NumberOfHandledRXPackersInDPC, step, 0, 1 + HKR, Ndi\Params\PacketFilter, ParamDesc, 0, %PacketFilter% HKR, Ndi\Params\PacketFilter, Default,0, 1 HKR, Ndi\Params\PacketFilter, type, 0,
[COMMIT] [NetKVM] Changing driver and inf versioning to conform to other virtio drivers
repository: C:/dev/kvm-guest-drivers-windows branch: master commit 4dd50edea41a968f3b78edc35df58054f00785b9 Author: Yan Vugenfirer yvuge...@redhat.com Date: Wed Jul 13 14:54:07 2011 +0300 [NetKVM] Changing driver and inf versioning to conform to other virtio drivers diff --git a/NetKVM/buildAll.bat b/NetKVM/buildAll.bat index d4018b0..c66d84a 100644 --- a/NetKVM/buildAll.bat +++ b/NetKVM/buildAll.bat @@ -23,8 +23,13 @@ popd set BUILDROOT=C:\WINDDK\%DDKVER% set X64ENV=x64 if %DDKVER%==6000 set X64ENV=amd64 -set _MAJORVERSION_=209 -set _MINORVERSION_=605 + +if %_BUILD_MAJOR_VERSION_%== set _BUILD_MAJOR_VERSION_=101 +if %_BUILD_MINOR_VERSION_%== set _BUILD_MINOR_VERSION_=58000 +if %_RHEL_RELEASE_VERSION_%== set _RHEL_RELEASE_VERSION_=61 + +set _MAJORVERSION_=%_BUILD_MAJOR_VERSION_% +set _MINORVERSION_=%_BUILD_MINOR_VERSION_% set _DRIVER_ISO_NAME=Install-%_MINORVERSION_%%_MAJORVERSION_%.iso set OLD_PATH=%PATH% @@ -62,8 +67,13 @@ goto :eof :preparebuild echo DIRS=%* dirs for %%f in (%*) do echo !include $(NTMAKEENV)\makefile.def %%f\makefile -set /a _NT_TARGET_MAJ=%_NT_TARGET_VERSION% 8 -set /a _NT_TARGET_MIN=%_NT_TARGET_VERSION% 255 +set /a _NT_TARGET_MAJ_ARCH=%_NT_TARGET_VERSION% 8 +set /a _NT_TARGET_MIN_ARCH=%_NT_TARGET_VERSION% 255 + +set /a _NT_TARGET_MAJ=(%_NT_TARGET_VERSION% 8) * 10 + (%_NT_TARGET_VERSION% 255) +set _NT_TARGET_MIN=%_RHEL_RELEASE_VERSION_% +rem set STAMPINF_VERSION=%_NT_TARGET_MAJ%.%_RHEL_RELEASE_VERSION_%.%_BUILD_MAJOR_VERSION_%.%_BUILD_MINOR_VERSION_% + set _VERSION_=%_NT_TARGET_MAJ%.%_NT_TARGET_MIN%.%_MAJORVERSION_%.%_MINORVERSION_% echo version set: %_VERSION_% goto :eof diff --git a/NetKVM/tools/signing.cmd b/NetKVM/tools/signing.cmd index f4c0a39..24c84cb 100644 --- a/NetKVM/tools/signing.cmd +++ b/NetKVM/tools/signing.cmd @@ -54,7 +54,7 @@ echo system %1 echo INF file %2 echo VERSION file %3 echo Target OS mask %_OSMASK_% -for /F usebackq tokens=2 %%d in (`date /t`) do stampinf -f %2 -d %%d -v %3 -a %_BUILDARCH%.%_NT_TARGET_MAJ%.%_NT_TARGET_MIN% +for /F usebackq tokens=2 %%d in (`date /t`) do stampinf -f %2 -d %%d -v %3 -a %_BUILDARCH%.%_NT_TARGET_MAJ_ARCH%.%_NT_TARGET_MIN_ARCH% inf2cat /driver:%~dp2 /os:%_OSMASK_% SignTool sign %SIGNCERT% %SIGNTIMESTAMP% %~dpn2.cat goto :eof @@ -69,7 +69,7 @@ if /i %1==x86 set _OSMASK_=256 if /i %1==amd64 set _OSMASK_=512 if /i %1==x64 set _OSMASK_=512 echo Target OS mask %_OSMASK_% -for /F usebackq tokens=2 %%d in (`date /t`) do stampinf -f %2 -d %%d -v %3 -a %_BUILDARCH%.%_NT_TARGET_MAJ%.%_NT_TARGET_MIN% +for /F usebackq tokens=2 %%d in (`date /t`) do stampinf -f %2 -d %%d -v %3 -a %_BUILDARCH%.%_NT_TARGET_MAJ_ARCH%.%_NT_TARGET_MIN_ARCH% signability /driver:%~dp2 /auto /cat /dtc /os:%_OSMASK_% taskkill /FI WINDOWTITLE eq signability* SignTool sign %SIGNCERT% %SIGNTIMESTAMP% %~dpn2.cat @@ -87,7 +87,7 @@ rem (128+16=144) xp64 + 2003-64 if /i %1==amd64 set _OSMASK_=144 if /i %1==x64 set _OSMASK_=144 echo Target OS mask %_OSMASK_% -for /F usebackq tokens=2 %%d in (`date /t`) do stampinf -f %2 -d %%d -v %3 -a %_BUILDARCH%.%_NT_TARGET_MAJ%.%_NT_TARGET_MIN% +for /F usebackq tokens=2 %%d in (`date /t`) do stampinf -f %2 -d %%d -v %3 -a %_BUILDARCH%.%_NT_TARGET_MAJ_ARCH%.%_NT_TARGET_MIN_ARCH% signability /driver:%~dp2 /auto /cat /os:%_OSMASK_% taskkill /FI WINDOWTITLE eq signability* SignTool sign %SIGNCERT% %SIGNTIMESTAMP% %~dpn2.cat -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [NetKVM] Debug printouts with timestamps to enable debugging of Power managment events (S3, S4)
repository: C:/dev/kvm-guest-drivers-windows branch: master commit e80717e6d341ba9657411baf34393363f9ec7f3d Author: Yan Vugenfirer yvuge...@redhat.com Date: Wed Jul 13 14:58:21 2011 +0300 [NetKVM] Debug printouts with timestamps to enable debugging of Power managment events (S3, S4) diff --git a/NetKVM/Common/ndis56common.h b/NetKVM/Common/ndis56common.h index f80c287..cfc2c7a 100644 --- a/NetKVM/Common/ndis56common.h +++ b/NetKVM/Common/ndis56common.h @@ -270,6 +270,7 @@ typedef struct _tagPARANDIS_ADAPTER BOOLEAN bDoKickOnNoBuffer; BOOLEAN bSurprizeRemoved; BOOLEAN bUsingMSIX; + UINTuNumberOfHandledRXPacketsInDPC; NDIS_DEVICE_POWER_STATE powerState; LONGdpcReceiveActive; LONGcounterDPCInside; diff --git a/NetKVM/wlh/ParaNdis6-Driver.c b/NetKVM/wlh/ParaNdis6-Driver.c index 9e7a06a..1c753d2 100644 --- a/NetKVM/wlh/ParaNdis6-Driver.c +++ b/NetKVM/wlh/ParaNdis6-Driver.c @@ -490,6 +490,7 @@ static NDIS_STATUS ParaNdis6_Restart( NDIS_STATUS status = NDIS_STATUS_SUCCESS; PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)miniportAdapterContext; DEBUG_ENTRY(0); + ParaNdis_DebugHistory(pContext, hopSysResume, NULL, 1, 0, 0); ParaNdis6_SendPauseRestart(pContext, FALSE, NULL); ParaNdis6_ReceivePauseRestart(pContext, FALSE, NULL); @@ -985,11 +986,21 @@ NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath { NDIS_STATUS status = NDIS_STATUS_FAILURE; NDIS_MINIPORT_DRIVER_CHARACTERISTICSchars; +#ifdef DEBUG_TIMING + LARGE_INTEGER TickCount; + LARGE_INTEGER SysTime; +#endif DEBUG_TIMING ParaNdis_DebugInitialize(pDriverObject, pRegistryPath); DEBUG_ENTRY(0); _LogOutString(0, __DATE__ __TIME__); +#ifdef DEBUG_TIMING + KeQueryTickCount(TickCount); + NdisGetCurrentSystemTime(SysTime); + DPrintf(0, (\n%s CPU #%d, perf-counter %I64d, tick count %I64d, NDIS_sys_time %I64d\n, __FUNCTION__, KeGetCurrentProcessorNumber(), KeQueryPerformanceCounter(NULL).QuadPart,TickCount.QuadPart, SysTime.QuadPart)); +#endif + NdisZeroMemory(chars, sizeof(chars)); chars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS; diff --git a/NetKVM/wlh/ParaNdis6-Oid.c b/NetKVM/wlh/ParaNdis6-Oid.c index e71e80c..86a2e68 100644 --- a/NetKVM/wlh/ParaNdis6-Oid.c +++ b/NetKVM/wlh/ParaNdis6-Oid.c @@ -441,6 +441,15 @@ static void OnSetPowerWorkItem(PVOID WorkItemContext, NDIS_HANDLE NdisIoWorkIt PARANDIS_ADAPTER *pContext = pwi-pContext; PNDIS_OID_REQUEST pRequest = (PNDIS_OID_REQUEST)pwi-request; NDIS_STATUS status = NDIS_STATUS_SUCCESS; +#ifdef DEBUG_TIMING + LARGE_INTEGER TickCount; + LARGE_INTEGER SysTime; + + KeQueryTickCount(TickCount); + NdisGetCurrentSystemTime(SysTime); + DPrintf(0, (\n%s CPU #%d, perf-counter %I64d, tick count %I64d, NDIS_sys_time %I64d\n, __FUNCTION__, KeGetCurrentProcessorNumber(), KeQueryPerformanceCounter(NULL).QuadPart,TickCount.QuadPart, SysTime.QuadPart)); +#endif + if (pwi-state == NetDeviceStateD0) { ParaNdis_PowerOn(pContext); @@ -463,7 +472,17 @@ NDIS_STATUS ParaNdis_OnSetPower(PARANDIS_ADAPTER *pContext, tOidDesc *pOid) { NDIS_STATUS status; NDIS_DEVICE_POWER_STATE newState; +#ifdef DEBUG_TIMING + LARGE_INTEGER TickCount; + LARGE_INTEGER SysTime; + + KeQueryTickCount(TickCount); + NdisGetCurrentSystemTime(SysTime); + DPrintf(0, (\n%s CPU #%d, perf-counter %I64d, tick count %I64d, NDIS_sys_time %I64d\n, __FUNCTION__, KeGetCurrentProcessorNumber(), KeQueryPerformanceCounter(NULL).QuadPart,TickCount.QuadPart, SysTime.QuadPart)); +#endif + DEBUG_ENTRY(0); + status = ParaNdis_OidSetCopy(pOid, newState, sizeof(newState)); if (status == NDIS_STATUS_SUCCESS) { -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [vioserial] associate virtio port with the driver.
From 212d89e1b381b69296d2fe9441161532417060ea Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 2 May 2011 22:08:44 +0300 Subject: [COMMIT] [vioserial] associate virtio port with the driver. --- vioserial/sys/vioser.inx | 10 +- 1 files changed, 9 insertions(+), 1 deletions(-) diff --git a/vioserial/sys/vioser.inx b/vioserial/sys/vioser.inx index ad397e9..1ad8617 100644 --- a/vioserial/sys/vioser.inx +++ b/vioserial/sys/vioser.inx @@ -39,15 +39,23 @@ vioser.sys = 1,, ; ones on XP and later. [VirtioSerial.NT$ARCH$] %VirtioSerial.DeviceDesc%=VirtioSerial_Device, PCI \VEN_1AF4DEV_1003SUBSYS_00031AF4 +%VirtioPort.DeviceDesc%=VirtioPort_Device, {6FDE7547-1B65-48ae-B628-80BE62016026}\VIOSerialPort [VirtioSerial_Device.NT] CopyFiles=Drivers_Dir +[VirtioPort_Device.NT] + + [Drivers_Dir] vioser.sys ;-- Service installation +[VirtioPort_Device.NT.Services] +AddService = ,%SPSVCINST_ASSOCSERVICE%, + + [VirtioSerial_Device.NT.Services] AddService = VirtioSerial,%SPSVCINST_ASSOCSERVICE%, VirtioSerial_Service_Inst @@ -94,4 +102,4 @@ RedHatMfg = VirtIO-Serial communcation device DiskId1 = VirtIO-Serial Installation Disk #1 VirtioSerial.DeviceDesc = VirtIO-Serial Driver VirtioSerial.SVCDESC = VirtIO-Serial Service - +VirtioPort.DeviceDesc = VirtIO-Serial Port RawPDO -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [vioserial] add resource file.
From 7feb63ba36e487c1ae89ab258f406f94e9861255 Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 2 May 2011 22:13:51 +0300 Subject: [COMMIT] [vioserial] add resource file. --- vioserial/sys/sources |3 ++- vioserial/sys/vioser.rc | 43 +++ 2 files changed, 45 insertions(+), 1 deletions(-) create mode 100644 vioserial/sys/vioser.rc diff --git a/vioserial/sys/sources b/vioserial/sys/sources index 2dd8f8a..48069d8 100644 --- a/vioserial/sys/sources +++ b/vioserial/sys/sources @@ -21,7 +21,8 @@ SOURCES= Driver.c \ Port.c\ Buffer.c \ utils.c \ - Control.c + Control.c \ + vioser.rc TARGET_DESTINATION=wdf diff --git a/vioserial/sys/vioser.rc b/vioserial/sys/vioser.rc new file mode 100644 index 000..cfa9944 --- /dev/null +++ b/vioserial/sys/vioser.rc @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2010 Red Hat, Inc. + * + * File: vioser.rc + * + * This file contains resource (version) definitions for viostor driver. + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * +**/ +#include windows.h +#include ntverp.h + +#define VER_FILETYPEVFT_DRV +#define VER_FILESUBTYPE VFT2_DRV_SYSTEM +#define VER_FILEDESCRIPTION_STR Red Hat VirtIO Serial driver +#define VER_INTERNALNAME_STRvioser.sys +#define VER_ORIGINALFILENAME_STRvioser.sys + +#undef VER_PRODUCTBUILD +#undef VER_PRODUCTBUILD_QFE +#undef VER_PRODUCTMAJORVERSION +#undef VER_PRODUCTMINORVERSION + +#undef VER_LEGALCOPYRIGHT_STR +#define VER_LEGALCOPYRIGHT_STR Copyright (C) 2010 Red Hat Inc. + +#undef VER_COMPANYNAME_STR +#define VER_COMPANYNAME_STR Red Hat Inc. + +#undef VER_PRODUCTNAME_STR +#define VER_PRODUCTNAME_STR Red Hat VirtIO Serial controller + +#define VER_LANGNEUTRAL + +#define VER_PRODUCTBUILD_MAJORVERSION_ +#define VER_PRODUCTBUILD_QFE_MINORVERSION_ +#define VER_PRODUCTMAJORVERSION _NT_TARGET_MAJ +#define VER_PRODUCTMINORVERSION _NT_TARGET_MIN + + +#include common.ver -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [vioserial] fix device id guid
From 0d7e40ad7e046e230aed8897d797291a4ad459c4 Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 2 May 2011 22:18:56 +0300 Subject: [COMMIT] [vioserial] fix device id guid --- vioserial/sys/vioser.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/vioserial/sys/vioser.h b/vioserial/sys/vioser.h index bbdb42b..467367b 100644 --- a/vioserial/sys/vioser.h +++ b/vioserial/sys/vioser.h @@ -102,7 +102,7 @@ WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(PORTS_DEVICE, GetPortsDevice) #define VIOSERIAL_DRIVER_MEMORY_TAG (ULONG)'rsIV' -#define PORT_DEVICE_ID L{6FDE7521-1B65-48ae-B628-80BE62016026}\ \VIOSerialPort\0 +#define PORT_DEVICE_ID L{6FDE7547-1B65-48ae-B628-80BE62016026}\ \VIOSerialPort\0 DEFINE_GUID(GUID_DEVCLASS_PORT_DEVICE, 0x6fde7547, 0x1b65, 0x48ae, 0xb6, 0x28, 0x80, 0xbe, 0x62, 0x1, 0x60, 0x26); -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [vioserial] Add device Id to the port name.
From d6c22f4cc4fe3ae9e12858aa75f3c943adebe7e2 Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 16 May 2011 13:57:51 +0300 Subject: [COMMIT] [vioserial] Add device Id to the port name --- vioserial/sys/Device.c |8 +- vioserial/sys/Port.c | 60 --- vioserial/sys/vioser.h |9 --- 3 files changed, 43 insertions(+), 34 deletions(-) diff --git a/vioserial/sys/Device.c b/vioserial/sys/Device.c index 544efa9..3b856eb 100644 --- a/vioserial/sys/Device.c +++ b/vioserial/sys/Device.c @@ -37,6 +37,8 @@ static NTSTATUS VIOSerialShutDownAllQueues(IN WDFOBJECT WdfDevice); #endif +static UINT gDeviceCount = 0; + static NTSTATUS VIOSerialInitInterruptHandling( @@ -86,6 +88,7 @@ VIOSerialEvtDeviceAdd( WDF_PNPPOWER_EVENT_CALLBACKS PnpPowerCallbacks; WDF_CHILD_LIST_CONFIGChildListConfig; PNP_BUS_INFORMATION busInfo; +PPORTS_DEVICEpContext = NULL; UNREFERENCED_PARAMETER(Driver); @@ -149,9 +152,12 @@ VIOSerialEvtDeviceAdd( return status; } +pContext = GetPortsDevice(hDevice); +pContext-DeviceId = gDeviceCount++; + busInfo.BusTypeGuid = GUID_DEVCLASS_PORT_DEVICE; busInfo.LegacyBusType = PNPBus; -busInfo.BusNumber = 0; +busInfo.BusNumber = pContext-DeviceId; WdfDeviceSetBusInformationForChildren(hDevice, busInfo); diff --git a/vioserial/sys/Port.c b/vioserial/sys/Port.c index d3c68e4..ec55da1 100644 --- a/vioserial/sys/Port.c +++ b/vioserial/sys/Port.c @@ -62,7 +62,7 @@ VIOSerialFindPortById( ASSERT(childInfo.Status == WdfChildListRetrieveDeviceSuccess); rawPdo = RawPdoSerialPortGetData(hChild); -if(rawPdo rawPdo-port-Id == id) +if(rawPdo rawPdo-port-PortId == id) { WdfChildListEndIteration(list, iterator); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,%s id = %d port = 0x%p\n, __FUNCTION__, id, rawPdo-port); @@ -83,14 +83,15 @@ VIOSerialAddPort( PPORTS_DEVICE pContext = GetPortsDevice(Device); NTSTATUSstatus = STATUS_SUCCESS; -TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,%s port = %d\n, __FUNCTION__, id); +TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,%s DeviceId = %d :: PortId = %d\n, __FUNCTION__, pContext-DeviceId, id); WDF_CHILD_IDENTIFICATION_DESCRIPTION_HEADER_INIT( port.Header, sizeof(port) ); -port.Id = id; +port.PortId = id; +port.DeviceId = pContext-DeviceId; port.NameString.Buffer = NULL; port.NameString.Length = 0; port.NameString.MaximumLength = 0; @@ -130,7 +131,7 @@ VIOSerialRemovePort( WDFCHILDLISTlist; WDF_CHILD_LIST_ITERATOR iterator; -TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,%s port = %d\n, __FUNCTION__, port-Id); +TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP,%s port = %d\n, __FUNCTION__, port-PortId); list = WdfFdoGetDefaultChildList(Device); WDF_CHILD_LIST_ITERATOR_INIT(iterator, @@ -163,7 +164,8 @@ VIOSerialRemovePort( } ASSERT(childInfo.Status == WdfChildListRetrieveDeviceSuccess); -if(vport.Id == port-Id) +if ((vport.PortId == port-PortId) +(vport.DeviceId == port-DeviceId)) { status = WdfChildListUpdateChildDescriptionAsMissing( list, @@ -181,7 +183,7 @@ VIOSerialRemovePort( if(vport.GuestConnected) { - VIOSerialSendCtrlMsg(vport.BusDevice, vport.Id, VIRTIO_CONSOLE_PORT_OPEN, 0); + VIOSerialSendCtrlMsg(vport.BusDevice, vport.PortId, VIRTIO_CONSOLE_PORT_OPEN, 0); } WdfSpinLockAcquire(vport.InBufLock); VIOSerialDiscardPortData(vport); @@ -263,7 +265,7 @@ VIOSerialRenewAllPorts( if(vport.GuestConnected) { - VIOSerialSendCtrlMsg(vport.BusDevice, vport.Id, VIRTIO_CONSOLE_PORT_OPEN, 1); + VIOSerialSendCtrlMsg(vport.BusDevice, vport.PortId, VIRTIO_CONSOLE_PORT_OPEN, 1); } } WdfChildListEndIteration(list, iterator); @@ -326,7 +328,7 @@ VIOSerialShutdownAllPorts( if(vport.GuestConnected) { - VIOSerialSendCtrlMsg(vport.BusDevice, vport.Id, VIRTIO_CONSOLE_PORT_OPEN, 0); + VIOSerialSendCtrlMsg(vport.BusDevice, vport.PortId, VIRTIO_CONSOLE_PORT_OPEN, 0); } WdfSpinLockAcquire(vport.InBufLock); @@ -356,7 +358,7 @@ VIOSerialInitPortConsole( TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, -- %s\n, __FUNCTION__); port-GuestConnected = TRUE; -VIOSerialSendCtrlMsg(port-BusDevice, port-Id, VIRTIO_CONSOLE_PORT_OPEN, 1); +VIOSerialSendCtrlMsg(port-BusDevice, port-PortId, VIRTIO_CONSOLE_PORT_OPEN, 1); } VOID @@ -463,16 +465,16 @@ VIOSerialPortSendPortReady( PRAWPDO_VIOSERIAL_PORT pdoData =
[COMMIT] [vioserial] Fix ports numbering problem.
From 1906d77900afdfdd1720a6d743ce69487904a6a0 Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 16 May 2011 14:05:58 +0300 Subject: [COMMIT] [vioserial] Fix ports numbering problem. --- vioserial/sys/Device.c |7 +-- 1 files changed, 5 insertions(+), 2 deletions(-) diff --git a/vioserial/sys/Device.c b/vioserial/sys/Device.c index 3b856eb..cd262fd 100644 --- a/vioserial/sys/Device.c +++ b/vioserial/sys/Device.c @@ -365,7 +365,10 @@ VIOSerialInitAllQueues( TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INIT, -- %s\n, __FUNCTION__); nr_ports = pContext-consoleConfig.max_nr_ports; - +if(pContext-isHostMultiport) +{ +nr_ports++; +} for(i = 0, j = 0; i nr_ports; i++) { in_vq = VirtIODeviceFindVirtualQueue(pContext-IODevice, i * 2, NULL); @@ -421,7 +424,7 @@ VIOSerialShutDownAllQueues( } } -nr_ports = pContext-consoleConfig.max_nr_ports - 1; +nr_ports = pContext-consoleConfig.max_nr_ports; for(i = 0; i nr_ports; i++ ) { if(pContext-in_vqs pContext-in_vqs[i]) -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [vioserial] use buffered mode for data transfer
From 6ae78d9f9c49fc22120d1a96f9012f2aa69ed485 Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 16 May 2011 14:32:37 +0300 Subject: [COMMIT] [vioserial] use buffered mode for data transfer --- vioserial/sys/Control.c |1 + vioserial/sys/Device.c | 19 --- vioserial/sys/IsrDpc.c | 54 +++- vioserial/sys/Port.c| 328 +++ vioserial/sys/vioser.h | 20 +--- 5 files changed, 160 insertions(+), 262 deletions(-) diff --git a/vioserial/sys/Control.c b/vioserial/sys/Control.c index 1d0a849..329feb4 100644 --- a/vioserial/sys/Control.c +++ b/vioserial/sys/Control.c @@ -1,5 +1,6 @@ #include precomp.h #include vioser.h +#include public.h #if defined(EVENT_TRACING) #include Control.tmh diff --git a/vioserial/sys/Device.c b/vioserial/sys/Device.c index cd262fd..27769b6 100644 --- a/vioserial/sys/Device.c +++ b/vioserial/sys/Device.c @@ -176,7 +176,6 @@ VIOSerialEvtDevicePrepareHardware( PPORTS_DEVICE pContext = GetPortsDevice(Device); bool bPortFound = FALSE; NTSTATUS status = STATUS_SUCCESS; -WDF_DMA_ENABLER_CONFIG dmaConfig; UINT nr_ports; PAGED_CODE(); @@ -249,24 +248,6 @@ VIOSerialEvtDevicePrepareHardware( VirtIOConsoleConfig-max_nr_ports %d \n, pContext-consoleConfig.max_nr_ports); } -pContext-MaximumTransferLength = PORT_MAXIMUM_TRANSFER_LENGTH; -WDF_DMA_ENABLER_CONFIG_INIT( dmaConfig, - WdfDmaProfileScatterGather64Duplex, - pContext-MaximumTransferLength ); - -status = WdfDmaEnablerCreate(Device, - dmaConfig, - WDF_NO_OBJECT_ATTRIBUTES, - pContext-DmaEnabler - ); - -if (!NT_SUCCESS (status)) -{ -TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, -WdfDmaEnablerCreate failed: 0x%x\n, status); -return status; -} - if(pContext-isHostMultiport) { WDF_OBJECT_ATTRIBUTES attributes; diff --git a/vioserial/sys/IsrDpc.c b/vioserial/sys/IsrDpc.c index 6dfadf6..fe78658 100644 --- a/vioserial/sys/IsrDpc.c +++ b/vioserial/sys/IsrDpc.c @@ -33,7 +33,6 @@ VIOSerialInterruptDpc( PPORTS_DEVICEpContext; PVIOSERIAL_PORT port; WDFDEVICEDevice; -WDFDMATRANSACTION dmaTransaction; ULONGinformation; @@ -41,7 +40,6 @@ VIOSerialInterruptDpc( PUCHAR systemBuffer; size_t Length; WDFREQUEST request; -BOOLEAN nonBlock; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_DPC, -- %s\n, __FUNCTION__); @@ -61,50 +59,40 @@ VIOSerialInterruptDpc( { struct virtqueue*out_vq = GetOutQueue(port); WdfSpinLockAcquire(port-InBufLock); - if (!port-GuestConnected) - { - VIOSerialDiscardPortData(port); - } if (!port-InBuf) { port-InBuf = VIOSerialGetInBuf(port); TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, %s::%d port-InBuf = %p\n, __FUNCTION__, __LINE__, port-InBuf); } + if (!port-GuestConnected) + { + VIOSerialDiscardPortData(port); + } WdfSpinLockRelease(port-InBufLock); - if (!VIOSerialWillReadBlock(port)) + if (port-InBuf) { - status = WdfIoQueueRetrieveNextRequest(port-PendingReadQueue, request); - if (NT_SUCCESS(status)) + if (port-PendingReadRequest) { - TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC,Got available read request\n); - status = WdfRequestRetrieveOutputBuffer(request, 0, systemBuffer, Length); - if (NT_SUCCESS(status)) + request = port-PendingReadRequest; + status = WdfRequestUnmarkCancelable(request); + if (status != STATUS_CANCELLED) { -information = (ULONG)VIOSerialFillReadBuf(port, systemBuffer, Length); -WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, information); +TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC,Got available read request\n); +status = WdfRequestRetrieveOutputBuffer(request, 0, systemBuffer, Length); +if (NT_SUCCESS(status)) +{ + port-PendingReadRequest = NULL; + information = (ULONG)VIOSerialFillReadBuf(port, systemBuffer, Length); + WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, information); +} + } + else + { +TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, Request = %p was cancelled\n, request);
[COMMIT] [vioserial] fix send buffer and remove port logic
From 55dc00d6c15d4bc34bca41f785c0509fc91275df Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 16 May 2011 14:41:20 +0300 Subject: [COMMIT] [vioserial] fix send buffer and remove port logic --- vioserial/sys/Buffer.c | 68 -- vioserial/sys/Control.c | 18 +++- vioserial/sys/vioser.h | 19 +--- 3 files changed, 89 insertions(+), 16 deletions(-) diff --git a/vioserial/sys/Buffer.c b/vioserial/sys/Buffer.c index 003a5ee..ded83c7 100644 --- a/vioserial/sys/Buffer.c +++ b/vioserial/sys/Buffer.c @@ -42,13 +42,76 @@ VIOSerialAllocateBuffer( return buf; } +SSIZE_T +VIOSerialSendBuffers( +IN PVIOSERIAL_PORT port, +IN PVOID buf, +IN SIZE_T count, +IN BOOLEAN nonblock +) +{ +UINT dummy; +SSIZE_T ret; +struct VirtIOBufferDescriptor sg; +struct virtqueue *vq = GetOutQueue(port); +PVOID ptr = buf; +SIZE_T len = count; +UINT elements = 0; +TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, -- %s buf = %p, length = %d\n, __FUNCTION__, buf, (int)count); + +WdfSpinLockAcquire(port-OutVqLock); +VIOSerialReclaimConsumedBuffers(port); + +while (len) +{ +do +{ + sg.physAddr = GetPhysicalAddress(ptr); + sg.ulSize = min(PAGE_SIZE, (unsigned long)len); + + ret = vq-vq_ops-add_buf(vq, sg, 1, 0, ptr); + if (ret == 0) + { + ptr = (PVOID)((LONG_PTR)ptr + sg.ulSize); + len -= sg.ulSize; + elements++; + } +} while ((ret == 0) (len 0)); + +vq-vq_ops-kick(vq); +port-OutVqFull = TRUE; +if (!nonblock) +{ + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, -- %s !nonblock \n, __FUNCTION__); + while(elements) + { + if(vq-vq_ops-get_buf(vq, dummy)) + { + elements--; + } + else + { + KeStallExecutionProcessor(100); + } + } +} +else +{ + //FIXME +} +} +WdfSpinLockRelease(port-OutVqLock); +TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, -- %s\n, __FUNCTION__); +return count; +} + VOID VIOSerialFreeBuffer( IN PPORT_BUFFER buf ) { ASSERT(buf); -TraceEvents(TRACE_LEVEL_INFORMATION, DBG_QUEUEING, -- %s buf = % p, buf-va_buf = %p\n, __FUNCTION__, buf, buf-va_buf); +TraceEvents(TRACE_LEVEL_VERBOSE, DBG_QUEUEING, -- %s buf = %p, buf-va_buf = %p\n, __FUNCTION__, buf, buf-va_buf); if (buf-va_buf) { ExFreePoolWithTag(buf-va_buf, VIOSERIAL_DRIVER_MEMORY_TAG); @@ -84,7 +147,6 @@ VIOSerialFillReadBuf( ) { PPORT_BUFFER buf; -struct virtqueue *vq = GetOutQueue(port); NTSTATUS status = STATUS_SUCCESS; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_QUEUEING, -- %s\n, __FUNCTION__); @@ -123,7 +185,7 @@ VIOSerialAddInBuf( NTSTATUS status = STATUS_SUCCESS; struct VirtIOBufferDescriptor sg; -TraceEvents(TRACE_LEVEL_INFORMATION, DBG_QUEUEING, -- %s buf = % p\n, __FUNCTION__, buf); +TraceEvents(TRACE_LEVEL_VERBOSE, DBG_QUEUEING, -- %s buf = %p \n, __FUNCTION__, buf); if (buf == NULL) { ASSERT(0); diff --git a/vioserial/sys/Control.c b/vioserial/sys/Control.c index 329feb4..7a9be7b 100644 --- a/vioserial/sys/Control.c +++ b/vioserial/sys/Control.c @@ -129,15 +129,13 @@ VIOSerialHandleCtrlMsg( break; case VIRTIO_CONSOLE_PORT_REMOVE: - if (port) - { - TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, VIRTIO_CONSOLE_PORT_REMOVE id = %d\n, cpkt-id); - VIOSerialRemovePort(Device, port); - } - else + if (!port) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, VIRTIO_CONSOLE_PORT_REMOVE invalid id = %d\n, cpkt-id); + break; } + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, VIRTIO_CONSOLE_PORT_REMOVE id = %d\n, cpkt-id); + VIOSerialRemovePort(Device, port); break; case VIRTIO_CONSOLE_CONSOLE_PORT: @@ -156,8 +154,12 @@ VIOSerialHandleCtrlMsg( case VIRTIO_CONSOLE_PORT_OPEN: if (port) { - TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, VIRTIO_CONSOLE_PORT_OPEN id = %d, HostConnected = %d\n, cpkt-id, cpkt-value); - port-HostConnected = (BOOLEAN)cpkt-value; + BOOLEAN Connected = (BOOLEAN)cpkt-value; + TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, VIRTIO_CONSOLE_PORT_OPEN id = %d, HostConnected = %d\n, cpkt-id, Connected); + if (port-HostConnected != Connected) + { + VIOSerialPortPnpNotify(Device, port, Connected); + } } else { diff --git a/vioserial/sys/vioser.h b/vioserial/sys/vioser.h index 2712a0f..3a47d60 100644 --- a/vioserial/sys/vioser.h
[COMMIT] [vioserial] make interface GUIDs public
From 42814cdfcb8d394d13a439e317a74863ddb61b81 Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 16 May 2011 14:59:01 +0300 Subject: [COMMIT] [vioserial] make interface GUIDs public --- vioserial/sys/Device.c |2 +- vioserial/sys/public.h | 12 vioserial/sys/vioser.h |4 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/vioserial/sys/Device.c b/vioserial/sys/Device.c index 27769b6..dcc335e 100644 --- a/vioserial/sys/Device.c +++ b/vioserial/sys/Device.c @@ -143,7 +143,7 @@ VIOSerialEvtDeviceAdd( status = WdfDeviceCreateDeviceInterface( hDevice, - GUID_DEVINTERFACE_PORTSENUM_VIOSERIAL, + GUID_VIOSERIAL_CONTROLLER, NULL ); if (!NT_SUCCESS(status)) diff --git a/vioserial/sys/public.h b/vioserial/sys/public.h index e3ed0c7..05f6ed5 100644 --- a/vioserial/sys/public.h +++ b/vioserial/sys/public.h @@ -15,6 +15,9 @@ #if !defined(VIOS_PUBLIC_H) #define VIOS_PUBLIC_H +DEFINE_GUID (GUID_VIOSERIAL_CONTROLLER, +0xF55F7844, 0x6A0C, 0x11d2, 0xB8, 0x41, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71); +// {F55F7844-6A0C-11d2-B841-00C04FAD5171} DEFINE_GUID(GUID_VIOSERIAL_PORT, 0x6fde7521, 0x1b65, 0x48ae, 0xb6, 0x28, 0x80, 0xbe, 0x62, 0x1, 0x60, 0x26); @@ -30,4 +33,13 @@ typedef struct _tagVirtioPortInfo { CHARName[1]; }VIRTIO_PORT_INFO, * PVIRTIO_PORT_INFO; +DEFINE_GUID(GUID_VIOSERIAL_PORT_CHANGE_STATUS, +0x2c0f39ac, 0xb156, 0x4237, 0x9c, 0x64, 0x89, 0x91, 0xa1, 0x8b, 0xf3, 0x5c); +// {2C0F39AC-B156-4237-9C64-8991A18BF35C} + +typedef struct _tagVirtioPortStatusChange { +ULONG Version; +ULONG Reason; +} VIRTIO_PORT_STATUS_CHANGE, *PVIRTIO_PORT_STATUS_CHANGE; + #endif /* VIOS_PUBLIC_H */ diff --git a/vioserial/sys/vioser.h b/vioserial/sys/vioser.h index 3a47d60..db1bd47 100644 --- a/vioserial/sys/vioser.h +++ b/vioserial/sys/vioser.h @@ -104,10 +104,6 @@ DEFINE_GUID(GUID_DEVCLASS_PORT_DEVICE, // {6FDE7547-1B65-48ae-B628-80BE62016026} -DEFINE_GUID (GUID_DEVINTERFACE_PORTSENUM_VIOSERIAL, -0xF55F7844, 0x6A0C, 0x11d2, 0xB8, 0x41, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71); -// {F55F7844-6A0C-11d2-B841-00C04FAD5171} - #define DEVICE_DESC_LENGTH 128 -- -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [vioserial] clean up interrupt enable/disable logic
From fd7cab2b8d58acf191a740856a11eb5952705fe6 Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 16 May 2011 15:30:14 +0300 Subject: [COMMIT] [vioserial] clean up interrupt enable/disable logic --- vioserial/sys/IsrDpc.c |8 vioserial/sys/Port.c |3 --- 2 files changed, 0 insertions(+), 11 deletions(-) diff --git a/vioserial/sys/IsrDpc.c b/vioserial/sys/IsrDpc.c index fe78658..6db9349 100644 --- a/vioserial/sys/IsrDpc.c +++ b/vioserial/sys/IsrDpc.c @@ -120,14 +120,6 @@ VIOSerialEnableDisableInterrupt( } } -if(pContext-c_ovq) -{ -pContext-c_ovq-vq_ops-enable_interrupt(pContext-c_ovq, bEnable); -if(bEnable) -{ - pContext-c_ovq-vq_ops-kick(pContext-c_ovq); -} -} TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INTERRUPT, -- %s enable = %d\n, __FUNCTION__, bEnable); } diff --git a/vioserial/sys/Port.c b/vioserial/sys/Port.c index 719bc10..71b65cf 100644 --- a/vioserial/sys/Port.c +++ b/vioserial/sys/Port.c @@ -181,7 +181,6 @@ VIOSerialRemovePort( } VIOSerialEnableDisableInterruptQueue(GetInQueue(vport), FALSE); - VIOSerialEnableDisableInterruptQueue(GetOutQueue(vport), FALSE); if(vport.GuestConnected) { @@ -263,7 +262,6 @@ VIOSerialRenewAllPorts( } VIOSerialEnableDisableInterruptQueue(GetInQueue(vport), TRUE); -VIOSerialEnableDisableInterruptQueue(GetOutQueue(vport), TRUE); if(vport.GuestConnected) { @@ -326,7 +324,6 @@ VIOSerialShutdownAllPorts( } VIOSerialEnableDisableInterruptQueue(GetInQueue(vport), FALSE); -VIOSerialEnableDisableInterruptQueue(GetOutQueue(vport), FALSE); if(vport.GuestConnected) { -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [vioserial] Fix rc file compilation problem
[vrozenfe@localhost vioserial]$ cat 0010-vioserial-Fix-rc-file-compilation-problem.patch From 03cf597917f908f8d421ea180873885742d96dfa Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 16 May 2011 15:46:34 +0300 Subject: [COMMIT] [vioserial] Fix rc file compilation problem --- vioserial/sys/vioser.rc |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/vioserial/sys/vioser.rc b/vioserial/sys/vioser.rc index cfa9944..6e7087c 100644 --- a/vioserial/sys/vioser.rc +++ b/vioserial/sys/vioser.rc @@ -18,6 +18,10 @@ #define VER_INTERNALNAME_STRvioser.sys #define VER_ORIGINALFILENAME_STRvioser.sys +#undef VER_FILEVERSION +#undef VER_FILEVERSION_STR +#undef VER_PRODUCTVERSION +#undef VER_PRODUCTVERSION_STR #undef VER_PRODUCTBUILD #undef VER_PRODUCTBUILD_QFE #undef VER_PRODUCTMAJORVERSION -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [viostor] check if msi-x is enabled
From 9d8ae91934b34d303f43ff3c7613eb75bf519d3b Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 2 May 2011 14:07:49 +0300 Subject: [COMMIT] [viostor] check if msi-x is enabled --- viostor/virtio_pci.c |2 +- viostor/virtio_stor.c | 63 + viostor/virtio_stor.h |1 + 3 files changed, 65 insertions(+), 1 deletions(-) diff --git a/viostor/virtio_pci.c b/viostor/virtio_pci.c index 6bc75a1..33693c4 100644 --- a/viostor/virtio_pci.c +++ b/viostor/virtio_pci.c @@ -67,7 +67,7 @@ VirtIODeviceGet( RhelDbgPrint(TRACE_LEVEL_VERBOSE, (%s\n, __FUNCTION__)); -ioaddr = adaptExt-device_base + VIRTIO_PCI_CONFIG((adaptExt-msix_vectors 0)) + offset; +ioaddr = adaptExt-device_base + VIRTIO_PCI_CONFIG(adaptExt-msix_enabled) + offset; for (i = 0; i len; i++) { ptr[i] = ScsiPortReadPortUchar((PUCHAR)(ioaddr + i)); diff --git a/viostor/virtio_stor.c b/viostor/virtio_stor.c index 52e023b..0e683c0 100644 --- a/viostor/virtio_stor.c +++ b/viostor/virtio_stor.c @@ -198,6 +198,12 @@ VirtIoFindAdapter( ULONG vq_sz; USHORT pageNum; +#ifdef MSI_SUPPORTED +PPCI_COMMON_CONFIG pPciConf = NULL; +UCHAR pci_cfg_buf[256]; +ULONG pci_cfg_len; +#endif + UNREFERENCED_PARAMETER( HwContext ); UNREFERENCED_PARAMETER( BusInformation ); UNREFERENCED_PARAMETER( ArgumentString ); @@ -294,6 +300,63 @@ VirtIoFindAdapter( return SP_RETURN_ERROR; } +adaptExt-msix_enabled = FALSE; + +#ifdef MSI_SUPPORTED +pci_cfg_len = StorPortGetBusData (DeviceExtension, + PCIConfiguration, + ConfigInfo-SystemIoBusNumber, + (ULONG)ConfigInfo-SlotNumber, + (PVOID)pci_cfg_buf, + (ULONG)256); +if (pci_cfg_len == 256) +{ +UCHAR CapOffset; +PPCI_MSIX_CAPABILITY pMsixCapOffset; + +pPciConf = (PPCI_COMMON_CONFIG)pci_cfg_buf; +if ( (pPciConf-Status PCI_STATUS_CAPABILITIES_LIST) == 0) +{ + RhelDbgPrint(TRACE_LEVEL_INFORMATION, (NO CAPABILITIES_LIST \n)); +} +else +{ + if ( (pPciConf-HeaderType (~PCI_MULTIFUNCTION)) == PCI_DEVICE_TYPE ) + { + CapOffset = pPciConf-u.type0.CapabilitiesPtr; + while (CapOffset != 0) + { + pMsixCapOffset = (PPCI_MSIX_CAPABILITY)(pci_cfg_buf + CapOffset); + if ( pMsixCapOffset-Header.CapabilityID == PCI_CAPABILITY_ID_MSIX ) + { +RhelDbgPrint(TRACE_LEVEL_INFORMATION, (MessageControl.TableSize = %d\n, pMsixCapOffset-MessageControl.TableSize)); +RhelDbgPrint(TRACE_LEVEL_INFORMATION, (MessageControl.FunctionMask = %d\n, pMsixCapOffset-MessageControl.FunctionMask)); +RhelDbgPrint(TRACE_LEVEL_INFORMATION, (MessageControl.MSIXEnable = %d\n, pMsixCapOffset-MessageControl.MSIXEnable)); + +RhelDbgPrint(TRACE_LEVEL_INFORMATION, (MessageTable = %p\n, pMsixCapOffset-MessageTable)); +RhelDbgPrint(TRACE_LEVEL_INFORMATION, (PBATable = %d\n, pMsixCapOffset-PBATable)); +adaptExt-msix_enabled = (pMsixCapOffset-MessageControl.MSIXEnable == 1); +break; + } + else + { +CapOffset = pMsixCapOffset-Header.Next; +RhelDbgPrint(TRACE_LEVEL_INFORMATION, (CapabilityID = %x, Next CapOffset = %x\n, pMsixCapOffset-Header.CapabilityID, CapOffset)); + } + } + } + else + { + RhelDbgPrint(TRACE_LEVEL_FATAL, (NOT A PCI_DEVICE_TYPE \n)); + } +} +} +else +{ +RhelDbgPrint(TRACE_LEVEL_FATAL, (CANNOT READ PCI CONFIGURATION SPACE %d\n, pci_cfg_len)); +} +#endif + VirtIODeviceReset(DeviceExtension); ScsiPortWritePortUshort((PUSHORT)(adaptExt-device_base + VIRTIO_PCI_QUEUE_SEL), (USHORT)0); if (adaptExt-dump_mode) { diff --git a/viostor/virtio_stor.h b/viostor/virtio_stor.h index 94e8f66..dc0c07a 100644 --- a/viostor/virtio_stor.h +++ b/viostor/virtio_stor.h @@ -114,6 +114,7 @@ typedef struct _ADAPTER_EXTENSION { BOOLEAN dump_mode; LIST_ENTRYlist_head; ULONG msix_vectors; +BOOLEAN msix_enabled; ULONG features; BOOLEAN flush_done; #ifdef USE_STORPORT -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [viostor] adjust device queue depth according to virtual queue size when working in indirect mode
From aa00ad3b28701839f732533f8ac098c8f8d0b065 Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 2 May 2011 14:52:18 +0300 Subject: [COMMIT] [viostor] adjust device queue depth according to virtual queue size when working in indirect mode --- viostor/virtio_stor.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/viostor/virtio_stor.c b/viostor/virtio_stor.c index 0e683c0..be5bd05 100644 --- a/viostor/virtio_stor.c +++ b/viostor/virtio_stor.c @@ -385,7 +385,7 @@ VirtIoFindAdapter( adaptExt-indirect = CHECKBIT(adaptExt-features, VIRTIO_RING_F_INDIRECT_DESC); } if(adaptExt-indirect) { -adaptExt-queue_depth = 1; +adaptExt-queue_depth = pageNum; } #endif RhelDbgPrint(TRACE_LEVEL_INFORMATION, (breaks_number = %x queue_depth = %x\n, -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [viostor] initialize dpc only once
From 8fe0df57fc8c03d732a7c91a482c93e07a40bb81 Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 2 May 2011 15:47:45 +0300 Subject: [COMMIT] [viostor] initialize dpc only once --- viostor/virtio_stor.c | 22 -- viostor/virtio_stor.h |1 + 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/viostor/virtio_stor.c b/viostor/virtio_stor.c index be5bd05..14bbfb2 100644 --- a/viostor/virtio_stor.c +++ b/viostor/virtio_stor.c @@ -428,7 +428,7 @@ VirtIoPassiveInitializeRoutine ( StorPortInitializeDpc(DeviceExtension, adaptExt-completion_dpc, CompleteDpcRoutine); - +adaptExt-dpc_ok = TRUE; return TRUE; } #endif @@ -566,7 +566,7 @@ VirtIoHwInitialize( ScsiPortMoveMemory(adaptExt-inquiry_data.VendorSpecific, 0001, sizeof(0001)); #ifdef USE_STORPORT -if(!adaptExt-dump_mode) +if(!adaptExt-dump_mode !adaptExt-dpc_ok) { return StorPortEnablePassiveInitialization(DeviceExtension, VirtIoPassiveInitializeRoutine); } @@ -822,21 +822,15 @@ VirtIoAdapterControl( case ScsiRestartAdapter: { RhelDbgPrint(TRACE_LEVEL_VERBOSE, (ScsiRestartAdapter\n)); VirtIODeviceReset(DeviceExtension); +ScsiPortWritePortUshort((PUSHORT)(adaptExt-device_base + VIRTIO_PCI_QUEUE_SEL), (USHORT)0); +ScsiPortWritePortUshort((PUSHORT)(adaptExt-device_base + VIRTIO_PCI_QUEUE_PFN),(USHORT)0); adaptExt-pci_vq_info.vq = NULL; -#ifdef MSI_SUPPORTED -if(!adaptExt-dump_mode adaptExt-msix_vectors) { - adaptExt-pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0, adaptExt-msix_vectors); -} -#endif -if(!adaptExt-pci_vq_info.vq) { - adaptExt-pci_vq_info.vq = VirtIODeviceFindVirtualQueue(DeviceExtension, 0, 0); -} -if (!adaptExt-pci_vq_info.vq) + +if (!VirtIoHwInitialize(DeviceExtension)) { - RhelDbgPrint(TRACE_LEVEL_FATAL, (Cannot find snd virtual queue\n)); + RhelDbgPrint(TRACE_LEVEL_FATAL, (Cannot Initialize HW\n)); break; } -VirtIoHwInitialize(DeviceExtension); status = ScsiAdapterControlSuccess; break; } @@ -1198,7 +1192,7 @@ CompleteDPC( RemoveEntryList(vbr-list_entry); #ifdef USE_STORPORT -if(!adaptExt-dump_mode) { +if(!adaptExt-dump_mode adaptExt-dpc_ok) { InsertTailList(adaptExt-complete_list, vbr-list_entry); StorPortIssueDpc(DeviceExtension, adaptExt-completion_dpc, diff --git a/viostor/virtio_stor.h b/viostor/virtio_stor.h index dc0c07a..286769d 100644 --- a/viostor/virtio_stor.h +++ b/viostor/virtio_stor.h @@ -120,6 +120,7 @@ typedef struct _ADAPTER_EXTENSION { #ifdef USE_STORPORT LIST_ENTRYcomplete_list; STOR_DPC completion_dpc; +BOOLEAN dpc_ok; #if (INDIRECT_SUPPORTED) BOOLEAN indirect; #endif -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [viostor] add preliminary support for indirect buffers
From a830a195fd89dc2c15c712141fbc7580589e60cb Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 2 May 2011 15:57:10 +0300 Subject: [COMMIT] [viostor] add preliminary support for indirect buffers --- viostor/virtio_ring.c | 20 +--- viostor/virtio_stor.h | 10 +- viostor/virtio_stor_hw_helper.c | 24 +--- 3 files changed, 11 insertions(+), 43 deletions(-) diff --git a/viostor/virtio_ring.c b/viostor/virtio_ring.c index 1f1cca3..248ddb1 100644 --- a/viostor/virtio_ring.c +++ b/viostor/virtio_ring.c @@ -56,10 +56,10 @@ vring_add_indirect( struct vring_desc *desc = (struct vring_desc *)va; unsigned head; unsigned int i; -STOR_PHYSICAL_ADDRESS addr; +SCSI_PHYSICAL_ADDRESS addr; ULONG len; -addr = StorPortGetPhysicalAddress(vq-vq.DeviceExtension, NULL, desc, len); +addr = ScsiPortGetPhysicalAddress(vq-vq.DeviceExtension, NULL, desc, len); if (!addr.QuadPart) { return vq-vring.num; } @@ -126,8 +126,8 @@ vring_add_buf( vbr = (pblk_req) data; Srb = (PSCSI_REQUEST_BLOCK)vbr-req; srbExt = (PRHEL_SRB_EXTENSION)Srb-SrbExtension; -if (srbExt-addr (out + in) 1 vq-num_free) { -head = vring_add_indirect(vq, sg, out, in, srbExt-addr); +if ((out + in) 1 vq-num_free) { +head = vring_add_indirect(vq, sg, out, in, srbExt-desc); if (head != vq-vring.num) goto add_head; } @@ -252,23 +252,13 @@ detach_buf( unsigned int head) { unsigned int i; -PVOID addr; -#if (INDIRECT_SUPPORTED) -STOR_PHYSICAL_ADDRESS pa; -#endif /* Clear data ptr. */ vq-data[head] = NULL; /* Put back on free list: find end */ i = head; -#if (INDIRECT_SUPPORTED) -if (vq-vring.desc[i].flags VRING_DESC_F_INDIRECT) { -pa.QuadPart = vq-vring.desc[i].addr; -addr = StorPortGetVirtualAddress(vq-vq.DeviceExtension, pa); -StorPortFreePool(vq-vq.DeviceExtension, addr); -} -#endif + while (vq-vring.desc[i].flags VRING_DESC_F_NEXT) { i = vq-vring.desc[i].next; vq-num_free++; diff --git a/viostor/virtio_stor.h b/viostor/virtio_stor.h index 286769d..86329a1 100644 --- a/viostor/virtio_stor.h +++ b/viostor/virtio_stor.h @@ -117,13 +117,13 @@ typedef struct _ADAPTER_EXTENSION { BOOLEAN msix_enabled; ULONG features; BOOLEAN flush_done; +#ifdef INDIRECT_SUPPORTED +BOOLEAN indirect; +#endif #ifdef USE_STORPORT LIST_ENTRYcomplete_list; STOR_DPC completion_dpc; BOOLEAN dpc_ok; -#if (INDIRECT_SUPPORTED) -BOOLEAN indirect; -#endif #endif }ADAPTER_EXTENSION, *PADAPTER_EXTENSION; @@ -134,8 +134,8 @@ typedef struct _RHEL_SRB_EXTENSION { #ifndef USE_STORPORT BOOLEAN call_next; #endif -#if (INDIRECT_SUPPORTED) -PVOID addr; +#if INDIRECT_SUPPORTED +struct vring_desc desc[VIRTIO_MAX_SG]; #endif }RHEL_SRB_EXTENSION, *PRHEL_SRB_EXTENSION; diff --git a/viostor/virtio_stor_hw_helper.c b/viostor/virtio_stor_hw_helper.c index 9cf6ded..8eb4324 100644 --- a/viostor/virtio_stor_hw_helper.c +++ b/viostor/virtio_stor_hw_helper.c @@ -157,29 +157,7 @@ BOOLEAN RhelDoReadWrite(PVOID DeviceExtension, PSCSI_REQUEST_BLOCK Srb) { -BOOLEAN res = FALSE; -PRHEL_SRB_EXTENSION srbExt = (PRHEL_SRB_EXTENSION)Srb-SrbExtension; -#if (INDIRECT_SUPPORTED) -NTSTATUS status = STATUS_SUCCESS; -struct vring_desc *desc = NULL; -srbExt-addr = NULL; -#endif -res = StorPortSynchronizeAccess(DeviceExtension, SynchronizedReadWriteRoutine, (PVOID)Srb); -#if (INDIRECT_SUPPORTED) - -if (!res) { -status = StorPortAllocatePool(DeviceExtension, - (srbExt-out + srbExt-in) * sizeof(struct vring_desc), - 'rdnI', (PVOID)desc); -if (!NT_SUCCESS(status)) { - RhelDbgPrint(TRACE_LEVEL_ERROR, (%s StorPortAllocatePool failed 0x%x\n, __FUNCTION__, status) ); - return FALSE; -} -srbExt-addr = desc; -res = StorPortSynchronizeAccess(DeviceExtension, SynchronizedReadWriteRoutine, (PVOID)Srb); -} -#endif -return res; +return StorPortSynchronizeAccess(DeviceExtension, SynchronizedReadWriteRoutine, (PVOID)Srb); } #else BOOLEAN -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [viostor] complete flush requests synchronously
From cf6f4ecb43db044d4f3028af0a23ec574289b285 Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 2 May 2011 16:03:44 +0300 Subject: [COMMIT] [viostor] complete flush requests synchronously --- viostor/virtio_stor.c |8 +++- viostor/virtio_stor_hw_helper.c | 15 +-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/viostor/virtio_stor.c b/viostor/virtio_stor.c index 14bbfb2..c0c6fbc 100644 --- a/viostor/virtio_stor.c +++ b/viostor/virtio_stor.c @@ -948,7 +948,13 @@ VirtIoMSInterruptRoutine ( Srb-SrbStatus = SRB_STATUS_ERROR; break; } - CompleteDPC(DeviceExtension, vbr, MessageID); + if (vbr-out_hdr.type == VIRTIO_BLK_T_FLUSH) { +adaptExt-flush_done = TRUE; + } + else + { +CompleteDPC(DeviceExtension, vbr, MessageID); + } } return TRUE; diff --git a/viostor/virtio_stor_hw_helper.c b/viostor/virtio_stor_hw_helper.c index 8eb4324..1785066 100644 --- a/viostor/virtio_stor_hw_helper.c +++ b/viostor/virtio_stor_hw_helper.c @@ -57,16 +57,19 @@ RhelDoFlush( { PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension; ULONG i; -ULONG Wait = 10; +ULONG Wait = 1; ASSERT(adaptExt-flush_done != TRUE); if(StorPortSynchronizeAccess(DeviceExtension, SynchronizedFlushRoutine, (PVOID)Srb)) { for (i = 0; i Wait; i++) { - StorPortStallExecution(1000); if (adaptExt-flush_done == TRUE) { adaptExt-flush_done = FALSE; return Srb-SrbStatus; } + StorPortStallExecution(500); + if (adaptExt-dump_mode) { + VirtIoInterrupt(DeviceExtension); + } } } return SRB_STATUS_ERROR; @@ -83,7 +86,7 @@ RhelDoFlush( ULONG fragLen; int num_free; ULONG i; -ULONG Wait = 10; +ULONG Wait = 1; ULONG status = SRB_STATUS_ERROR; srbExt-vbr.out_hdr.sector = 0; @@ -98,6 +101,7 @@ RhelDoFlush( srbExt-vbr.sg[1].physAddr = ScsiPortGetPhysicalAddress(DeviceExtension, NULL, srbExt-vbr.status, fragLen); srbExt-vbr.sg[1].ulSize = sizeof(srbExt-vbr.status); + num_free = adaptExt-pci_vq_info.vq-vq_ops-add_buf(adaptExt-pci_vq_info.vq, srbExt-vbr.sg[0], srbExt-out, srbExt-in, @@ -110,7 +114,7 @@ RhelDoFlush( status = Srb-SrbStatus; break; } - ScsiPortStallExecution(1000); + ScsiPortStallExecution(500); VirtIoInterrupt(DeviceExtension); } } @@ -140,6 +144,7 @@ SynchronizedReadWriteRoutine( PADAPTER_EXTENSION adaptExt = (PADAPTER_EXTENSION)DeviceExtension; PSCSI_REQUEST_BLOCK Srb = (PSCSI_REQUEST_BLOCK) Context; PRHEL_SRB_EXTENSION srbExt = (PRHEL_SRB_EXTENSION)Srb-SrbExtension; + if (adaptExt-pci_vq_info.vq-vq_ops-add_buf(adaptExt-pci_vq_info.vq, srbExt-vbr.sg[0], srbExt-out, srbExt-in, @@ -148,7 +153,6 @@ SynchronizedReadWriteRoutine( adaptExt-pci_vq_info.vq-vq_ops-kick(adaptExt-pci_vq_info.vq); return TRUE; } - StorPortBusy(DeviceExtension, 5); return FALSE; } @@ -289,6 +293,5 @@ RhelGetLba( return (ULONGLONG)-1; } } - return (lba.AsULongLong * (adaptExt-info.blk_size / SECTOR_SIZE)); } -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [balloon] use wdk macro for obtaining PFN associated with MDL
From b1cf55a481d2cbcd3beb93360dcb7b53a24d743d Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 2 May 2011 21:13:11 +0300 Subject: [COMMIT] [balloon] use wdk macro for obtaining PFN associated with MDL. --- Balloon/sys/balloon.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/Balloon/sys/balloon.c b/Balloon/sys/balloon.c index 177d74b..39ad3bc 100644 --- a/Balloon/sys/balloon.c +++ b/Balloon/sys/balloon.c @@ -190,7 +190,7 @@ BalloonFill( } pNewPageListEntry-PageMdl = pPageMdl; -pNewPageListEntry-PagePfn = drvCtx-pfns_table[drvCtx-num_pfns] = *(PPFN_NUMBER)(pPageMdl + 1); +pNewPageListEntry-PagePfn = drvCtx-pfns_table[drvCtx-num_pfns] = *MmGetMdlPfnArray(pPageMdl); WdfSpinLockAcquire(drvCtx-SpinLock); PushEntryList(drvCtx-PageListHead, (pNewPageListEntry-SingleListEntry)); -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT] [balloon] check balloon size on device init.
From 1c114e00b389a1df20addc6fa2cfb736d655f2a8 Mon Sep 17 00:00:00 2001 From: Vadim Rozenfeld vroze...@redhat.com Date: Mon, 2 May 2011 21:29:12 +0300 Subject: [COMMIT] [balloon] check balloon size on device init. --- Balloon/sys/ProtoTypes.h |4 Balloon/sys/balloon.c| 34 ++ 2 files changed, 38 insertions(+), 0 deletions(-) diff --git a/Balloon/sys/ProtoTypes.h b/Balloon/sys/ProtoTypes.h index 85c5f05..099d97e 100644 --- a/Balloon/sys/ProtoTypes.h +++ b/Balloon/sys/ProtoTypes.h @@ -194,6 +194,10 @@ DisableInterrupt( } } +VOID +FillLeakWorkItem( +IN WDFWORKITEM WorkItem +); VOID SetBalloonSize( diff --git a/Balloon/sys/balloon.c b/Balloon/sys/balloon.c index 39ad3bc..9d90eeb 100644 --- a/Balloon/sys/balloon.c +++ b/Balloon/sys/balloon.c @@ -80,7 +80,41 @@ free_mem: if(NT_SUCCESS(status)) { +LONGLONG diff = GetBalloonSize(WdfDevice); VirtIODeviceAddStatus(devCtx-VDevice, VIRTIO_CONFIG_S_DRIVER_OK); + +if (diff != 0) { + PWORKITEM_CONTEXT context; + WDF_OBJECT_ATTRIBUTES attributes; + WDF_WORKITEM_CONFIG workitemConfig; + WDFWORKITEM hWorkItem; + WDF_OBJECT_ATTRIBUTES_INIT(attributes); + WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE(attributes, WORKITEM_CONTEXT); + attributes.ParentObject = WdfDevice; + + WDF_WORKITEM_CONFIG_INIT(workitemConfig, FillLeakWorkItem); + + status = WdfWorkItemCreate( workitemConfig, +attributes, +hWorkItem); + + if (NT_SUCCESS(status)) { + context = GetWorkItemContext(hWorkItem); + + context-Device = WdfDevice; + context-Diff = GetBalloonSize(WdfDevice); + + context-bStatUpdate = FALSE; + + WdfWorkItemEnqueue(hWorkItem); + + } + else + { + VirtIODeviceAddStatus(devCtx-VDevice, VIRTIO_CONFIG_S_FAILED); + TraceEvents(TRACE_LEVEL_INFORMATION, DBG_DPC, WdfWorkItemCreate failed with status = 0x%08x\n, status); + } +} } else { -- 1.7.0.2.msysgit.0 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] kvmclock_test: fix smp initialization
From: Avi Kivity a...@redhat.com cpu_count() is not valid before smp_init(). Signed-off-by: Avi Kivity a...@redhat.com diff --git a/x86/kvmclock_test.c b/x86/kvmclock_test.c index 5b14ae2..52a43fb 100644 --- a/x86/kvmclock_test.c +++ b/x86/kvmclock_test.c @@ -115,7 +115,7 @@ static int cycle_test(int ncpus, long loops, int check, struct test_info *ti) int main(int ac, char **av) { -int ncpus = cpu_count(); +int ncpus; int nerr = 0, i; long loops = DEFAULT_TEST_LOOPS; long sec = 0; @@ -130,6 +130,7 @@ int main(int ac, char **av) smp_init(); +ncpus = cpu_count(); if (ncpus MAX_CPU) ncpus = MAX_CPU; for (i = 0; i ncpus; ++i) -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] qemu-kvm: Drop redundant kvm_reset_mpstate
From: Jan Kiszka jan.kis...@siemens.com kvm_arch_reset_vcpu includes the same logic (minus the obsolete feature check), and every caller of kvm_reset_mpstate also calls that function. Signed-off-by: Jan Kiszka jan.kis...@siemens.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c index 672bcbf..2f1a090 100644 --- a/qemu-kvm-x86.c +++ b/qemu-kvm-x86.c @@ -564,20 +564,6 @@ static void kvm_arch_load_mpstate(CPUState *env) #endif } -static void kvm_reset_mpstate(CPUState *env) -{ -#ifdef KVM_CAP_MP_STATE -if (kvm_check_extension(kvm_state, KVM_CAP_MP_STATE)) { -if (kvm_irqchip_in_kernel()) { -env-mp_state = cpu_is_bsp(env) ? KVM_MP_STATE_RUNNABLE : - KVM_MP_STATE_UNINITIALIZED; -} else { -env-mp_state = KVM_MP_STATE_RUNNABLE; -} -} -#endif -} - #define XSAVE_CWD_RIP 2 #define XSAVE_CWD_RDP 4 #define XSAVE_MXCSR 6 @@ -652,7 +638,6 @@ static int _kvm_arch_init_vcpu(CPUState *env) #ifdef KVM_EXIT_TPR_ACCESS kvm_enable_tpr_access_reporting(env); #endif -kvm_reset_mpstate(env); return 0; } @@ -761,7 +746,6 @@ void kvm_arch_cpu_reset(CPUState *env) { kvm_reset_msrs(env); kvm_arch_reset_vcpu(env); -kvm_reset_mpstate(env); } #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Merge branch 'upstream-merge'
From: Marcelo Tosatti mtosa...@redhat.com * upstream-merge: (279 commits) target-ppc: Implement correct NaN propagation rules target-mips: Implement correct NaN propagation rules softfloat: use float{32,64,x80,128}_maybe_silence_nan() softfloat: add float{x80,128}_maybe_silence_nan() softfloat: fix float{32,64}_maybe_silence_nan() for MIPS softfloat: rename *IsNaN variables to *IsQuietNaN softfloat: remove HPPA specific code target-ppc: use float32_is_any_nan() target-ppc: fix default qNaN target-ppc: remove PRECISE_EMULATION define microblaze: Use more TB chaining cirrus_vga: fix division by 0 for color expansion rop Fix curses on big endian hosts noaudio: correctly account acquired samples target-arm: Implement correct NaN propagation rules softfloat: abstract out target-specific NaN propagation rules softfloat: Rename float*_is_nan() functions to float*_is_quiet_nan() TCG: Improve tb_phys_hash_func() target-arm: fix UMAAL instruction Fix translation of unary PPC/SPE instructions (efdneg etc.). ... Signed-off-by: Marcelo Tosatti mtosa...@redhat.com -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] remove qemu-kvm.h inclusion from monitor.c
From: Marcelo Tosatti mtosa...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/monitor.c b/monitor.c index cf1d3d0..40768bb 100644 --- a/monitor.c +++ b/monitor.c @@ -61,7 +61,6 @@ #include trace.h #endif #include ui/qemu-spice.h -#include qemu-kvm.h //#define DEBUG //#define DEBUG_COMPLETION -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] pci-assign: Fix transition MSI-INTx
From: Jan Kiszka jan.kis...@siemens.com Make sure to re-register the IRQ of an assigned device as INTx when the guest disables MSI[X] mode again. Acked-by: Michael S. Tsirkin m...@redhat.com Acked-by: Alex Williamson alex.william...@redhat.com Signed-off-by: Jan Kiszka jan.kis...@siemens.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/hw/device-assignment.c b/hw/device-assignment.c index a25f3e0..e97f565 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -1136,7 +1136,10 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev, unsigned int ctrl_pos) if (kvm_assign_irq(kvm_context, assigned_irq_data) 0) perror(assigned_dev_enable_msi: assign irq); +assigned_dev-girq = -1; assigned_dev-irq_requested_type = assigned_irq_data.flags; +} else { +assign_irq(assigned_dev); } } #endif @@ -1276,7 +1279,10 @@ static void assigned_dev_update_msix(PCIDevice *pci_dev, unsigned int ctrl_pos) perror(assigned_dev_enable_msix: assign irq); return; } +assigned_dev-girq = -1; assigned_dev-irq_requested_type = assigned_irq_data.flags; +} else { +assign_irq(assigned_dev); } } #endif -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: MMU: Don't flush shadow when enabling dirty tracking
From: Avi Kivity a...@redhat.com Instead, drop large mappings, which were the reason we dropped shadow. Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 9cafbb4..772d212 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3445,14 +3445,18 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot) if (!test_bit(slot, sp-slot_bitmap)) continue; - if (sp-role.level != PT_PAGE_TABLE_LEVEL) - continue; - pt = sp-spt; - for (i = 0; i PT64_ENT_PER_PAGE; ++i) + for (i = 0; i PT64_ENT_PER_PAGE; ++i) { + if (sp-role.level != PT_PAGE_TABLE_LEVEL +is_large_pte(pt[i])) { + drop_spte(kvm, pt[i], + shadow_trap_nonpresent_pte); + --kvm-stat.lpages; + } /* avoid RMW */ if (is_writable_pte(pt[i])) update_spte(pt[i], pt[i] ~PT_WRITABLE_MASK); + } } kvm_flush_remote_tlbs(kvm); } diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b1b6cbb..b3bfeb8 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -586,7 +586,7 @@ int __kvm_set_memory_region(struct kvm *kvm, struct kvm_userspace_memory_region *mem, int user_alloc) { - int r, flush_shadow = 0; + int r; gfn_t base_gfn; unsigned long npages; unsigned long i; @@ -706,8 +706,6 @@ skip_lpage: if (kvm_create_dirty_bitmap(new) 0) goto out_free; /* destroy any largepage mappings for dirty tracking */ - if (old.npages) - flush_shadow = 1; } #else /* not defined CONFIG_S390 */ new.user_alloc = user_alloc; @@ -778,9 +776,6 @@ skip_lpage: kvm_free_physmem_slot(old, new); kfree(old_memslots); - if (flush_shadow) - kvm_arch_flush_shadow(kvm); - return 0; out_free: -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: PPC: Fix SPRG get/set for Book3S and BookE
From: Peter Tyser pty...@xes-inc.com Previously SPRGs 4-7 were improperly read and written in kvm_arch_vcpu_ioctl_get_regs() and kvm_arch_vcpu_ioctl_set_regs(); Signed-off-by: Alexander Graf ag...@suse.de Signed-off-by: Peter Tyser pty...@xes-inc.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index badc983..c961de4 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -1141,9 +1141,10 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) regs-sprg1 = vcpu-arch.shared-sprg1; regs-sprg2 = vcpu-arch.shared-sprg2; regs-sprg3 = vcpu-arch.shared-sprg3; - regs-sprg5 = vcpu-arch.sprg4; - regs-sprg6 = vcpu-arch.sprg5; - regs-sprg7 = vcpu-arch.sprg6; + regs-sprg4 = vcpu-arch.sprg4; + regs-sprg5 = vcpu-arch.sprg5; + regs-sprg6 = vcpu-arch.sprg6; + regs-sprg7 = vcpu-arch.sprg7; for (i = 0; i ARRAY_SIZE(regs-gpr); i++) regs-gpr[i] = kvmppc_get_gpr(vcpu, i); @@ -1167,9 +1168,10 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) vcpu-arch.shared-sprg1 = regs-sprg1; vcpu-arch.shared-sprg2 = regs-sprg2; vcpu-arch.shared-sprg3 = regs-sprg3; - vcpu-arch.sprg5 = regs-sprg4; - vcpu-arch.sprg6 = regs-sprg5; - vcpu-arch.sprg7 = regs-sprg6; + vcpu-arch.sprg4 = regs-sprg4; + vcpu-arch.sprg5 = regs-sprg5; + vcpu-arch.sprg6 = regs-sprg6; + vcpu-arch.sprg7 = regs-sprg7; for (i = 0; i ARRAY_SIZE(regs-gpr); i++) kvmppc_set_gpr(vcpu, i, regs-gpr[i]); diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 77575d0..ef76acb 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -546,9 +546,10 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) regs-sprg1 = vcpu-arch.shared-sprg1; regs-sprg2 = vcpu-arch.shared-sprg2; regs-sprg3 = vcpu-arch.shared-sprg3; - regs-sprg5 = vcpu-arch.sprg4; - regs-sprg6 = vcpu-arch.sprg5; - regs-sprg7 = vcpu-arch.sprg6; + regs-sprg4 = vcpu-arch.sprg4; + regs-sprg5 = vcpu-arch.sprg5; + regs-sprg6 = vcpu-arch.sprg6; + regs-sprg7 = vcpu-arch.sprg7; for (i = 0; i ARRAY_SIZE(regs-gpr); i++) regs-gpr[i] = kvmppc_get_gpr(vcpu, i); @@ -572,9 +573,10 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) vcpu-arch.shared-sprg1 = regs-sprg1; vcpu-arch.shared-sprg2 = regs-sprg2; vcpu-arch.shared-sprg3 = regs-sprg3; - vcpu-arch.sprg5 = regs-sprg4; - vcpu-arch.sprg6 = regs-sprg5; - vcpu-arch.sprg7 = regs-sprg6; + vcpu-arch.sprg4 = regs-sprg4; + vcpu-arch.sprg5 = regs-sprg5; + vcpu-arch.sprg6 = regs-sprg6; + vcpu-arch.sprg7 = regs-sprg7; for (i = 0; i ARRAY_SIZE(regs-gpr); i++) kvmppc_set_gpr(vcpu, i, regs-gpr[i]); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM guest: Fix section mismatch derived from kvm_guest_cpu_online()
From: Sedat Dilek sedat.di...@googlemail.com WARNING: arch/x86/built-in.o(.text+0x1bb74): Section mismatch in reference from the function kvm_guest_cpu_online() to the function .cpuinit.text:kvm_guest_cpu_init() The function kvm_guest_cpu_online() references the function __cpuinit kvm_guest_cpu_init(). This is often because kvm_guest_cpu_online lacks a __cpuinit annotation or the annotation of kvm_guest_cpu_init is wrong. This patch fixes the warning. Tested with linux-next (next-20101231) Signed-off-by: Sedat Dilek sedat.di...@gmail.com Acked-by: Rik van Riel r...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 8dc4466..33c07b0 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -493,7 +493,7 @@ static void __init kvm_smp_prepare_boot_cpu(void) native_smp_prepare_boot_cpu(); } -static void kvm_guest_cpu_online(void *dummy) +static void __cpuinit kvm_guest_cpu_online(void *dummy) { kvm_guest_cpu_init(); } -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
From: Marcelo Tosatti mtosa...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: VMX: Avoid leaking fake realmode state to userspace
From: Avi Kivity a...@redhat.com When emulating real mode, we fake some state: - tr.base points to a fake vm86 tss - segment registers are made to conform to vm86 restrictions change vmx_get_segment() not to expose this fake state to userspace; instead, return the original state. Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a2e83a9..87ad551 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2032,23 +2032,40 @@ static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) vmcs_writel(GUEST_CR4, hw_cr4); } -static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg) -{ - struct kvm_vmx_segment_field *sf = kvm_vmx_segment_fields[seg]; - - return vmcs_readl(sf-base); -} - static void vmx_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) { + struct vcpu_vmx *vmx = to_vmx(vcpu); struct kvm_vmx_segment_field *sf = kvm_vmx_segment_fields[seg]; + struct kvm_save_segment *save; u32 ar; + if (vmx-rmode.vm86_active +(seg == VCPU_SREG_TR || seg == VCPU_SREG_ES + || seg == VCPU_SREG_DS || seg == VCPU_SREG_FS + || seg == VCPU_SREG_GS) +!emulate_invalid_guest_state) { + switch (seg) { + case VCPU_SREG_TR: save = vmx-rmode.tr; break; + case VCPU_SREG_ES: save = vmx-rmode.es; break; + case VCPU_SREG_DS: save = vmx-rmode.ds; break; + case VCPU_SREG_FS: save = vmx-rmode.fs; break; + case VCPU_SREG_GS: save = vmx-rmode.gs; break; + default: BUG(); + } + var-selector = save-selector; + var-base = save-base; + var-limit = save-limit; + ar = save-ar; + if (seg == VCPU_SREG_TR + || var-selector == vmcs_read16(sf-selector)) + goto use_saved_rmode_seg; + } var-base = vmcs_readl(sf-base); var-limit = vmcs_read32(sf-limit); var-selector = vmcs_read16(sf-selector); ar = vmcs_read32(sf-ar_bytes); +use_saved_rmode_seg: if ((ar AR_UNUSABLE_MASK) !emulate_invalid_guest_state) ar = 0; var-type = ar 15; @@ -2062,6 +2079,18 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu, var-unusable = (ar 16) 1; } +static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg) +{ + struct kvm_vmx_segment_field *sf = kvm_vmx_segment_fields[seg]; + struct kvm_segment s; + + if (to_vmx(vcpu)-rmode.vm86_active) { + vmx_get_segment(vcpu, s, seg); + return s.base; + } + return vmcs_readl(sf-base); +} + static int vmx_get_cpl(struct kvm_vcpu *vcpu) { if (!is_protmode(vcpu)) -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: VMX: Save and restore tr selector across mode switches
From: Avi Kivity a...@redhat.com When emulating real mode we play with tr hidden state, but leave tr.selector alone. That works well, except for save/restore, since loading TR writes it to the hidden state in vmx-rmode. Fix by also saving and restoring the tr selector; this makes things more consistent and allows migration to work during the early boot stages of Windows XP. Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index bf89ec2..a2e83a9 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1683,6 +1683,7 @@ static void enter_pmode(struct kvm_vcpu *vcpu) vmx-emulation_required = 1; vmx-rmode.vm86_active = 0; + vmcs_write16(GUEST_TR_SELECTOR, vmx-rmode.tr.selector); vmcs_writel(GUEST_TR_BASE, vmx-rmode.tr.base); vmcs_write32(GUEST_TR_LIMIT, vmx-rmode.tr.limit); vmcs_write32(GUEST_TR_AR_BYTES, vmx-rmode.tr.ar); @@ -1756,6 +1757,7 @@ static void enter_rmode(struct kvm_vcpu *vcpu) vmx-emulation_required = 1; vmx-rmode.vm86_active = 1; + vmx-rmode.tr.selector = vmcs_read16(GUEST_TR_SELECTOR); vmx-rmode.tr.base = vmcs_readl(GUEST_TR_BASE); vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu-kvm)); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: Initialize fpu state in preemptible context
From: Avi Kivity a...@redhat.com init_fpu() (which is indirectly called by the fpu switching code) assumes it is in process context. Rather than makeing init_fpu() use an atomic allocation, which can cause a task to be killed, make sure the fpu is already initialized when we enter the run loop. KVM-Stable-Tag. Reported-and-tested-by: Kirill A. Shutemov k...@openvz.org Acked-by: Pekka Enberg penb...@kernel.org Reviewed-by: Christoph Lameter c...@linux.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index 58bb239..e60c38c 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c @@ -169,6 +169,7 @@ int init_fpu(struct task_struct *tsk) set_stopped_child_used_math(tsk); return 0; } +EXPORT_SYMBOL_GPL(init_fpu); /* * The xstateregs_active() routine is the same as the fpregs_active() routine, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index fa708c9..9dda70d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -5376,6 +5376,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) int r; sigset_t sigsaved; + if (!tsk_used_math(current) init_fpu(current)) + return -ENOMEM; + if (vcpu-sigset_active) sigprocmask(SIG_SETMASK, vcpu-sigset, sigsaved); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] smp: speed up cpu_count()
From: Avi Kivity a...@redhat.com cpu_count() is used in important places, like vmexit.flat's measuring loop, yet it is ridiculously slow as it talks to the firmware config interface. Speed it up by reading the value from memory. Signed-off-by: Avi Kivity a...@redhat.com diff --git a/lib/x86/smp.c b/lib/x86/smp.c index 8da614a..d41c332 100644 --- a/lib/x86/smp.c +++ b/lib/x86/smp.c @@ -78,7 +78,7 @@ void spin_unlock(struct spinlock *lock) int cpu_count(void) { -return fwcfg_get_nb_cpus(); +return _cpu_count; } int smp_id(void) @@ -130,6 +130,8 @@ void smp_init(void) int i; void ipi_entry(void); +_cpu_count = fwcfg_get_nb_cpus(); + set_ipi_descriptor(ipi_entry); setup_smp_id(0); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] vmexit: fix race in joining smp tests
From: Avi Kivity a...@redhat.com 'nr_cpus_done' is not incremented atomically; this has been observed to cause tests to stall. Fix by using a proper atomic increment. Signed-off-by: Avi Kivity a...@redhat.com diff --git a/x86/vmexit.c b/x86/vmexit.c index 875caa3..ad8ab55 100644 --- a/x86/vmexit.c +++ b/x86/vmexit.c @@ -2,6 +2,7 @@ #include libcflat.h #include smp.h #include processor.h +#include atomic.h static unsigned int inl(unsigned short port) { @@ -121,7 +122,7 @@ static struct test { }; unsigned iterations; -volatile int nr_cpus_done; +static atomic_t nr_cpus_done; static void run_test(void *_func) { @@ -131,7 +132,7 @@ static void run_test(void *_func) for (i = 0; i iterations; ++i) func(); -nr_cpus_done++; +atomic_inc(nr_cpus_done); } static void do_test(struct test *test) @@ -155,10 +156,10 @@ static void do_test(struct test *test) for (i = 0; i iterations; ++i) func(); } else { - nr_cpus_done = 0; + atomic_set(nr_cpus_done, 0); for (i = cpu_count(); i 0; i--) on_cpu_async(i-1, run_test, func); - while (nr_cpus_done cpu_count()) + while (atomic_read(nr_cpus_done) cpu_count()) ; } t2 = rdtsc(); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] smp: fix race in async on_cpu()
From: Avi Kivity a...@redhat.com We fire off the IPI, but don't wait for the other cpu to pickk up the function and data before returning. Fix by making the other cpu ACK the receipt of the IPI (but still execute the result asynchrously). Signed-off-by: Avi Kivity a...@redhat.com diff --git a/lib/x86/smp.c b/lib/x86/smp.c index 241f755..8da614a 100644 --- a/lib/x86/smp.c +++ b/lib/x86/smp.c @@ -7,15 +7,27 @@ #define IPI_VECTOR 0x20 static struct spinlock ipi_lock; -static void (*ipi_function)(void *data); -static void *ipi_data; +static volatile void (*ipi_function)(void *data); +static volatile void *ipi_data; static volatile int ipi_done; +static volatile bool ipi_wait; +static int _cpu_count; static __attribute__((used)) void ipi() { -ipi_function(ipi_data); -apic_write(APIC_EOI, 0); -ipi_done = 1; +void (*function)(void *data) = ipi_function; +void *data = ipi_data; +bool wait = ipi_wait; + +if (!wait) { + ipi_done = 1; + apic_write(APIC_EOI, 0); +} +function(data); +if (wait) { + ipi_done = 1; + apic_write(APIC_EOI, 0); +} } asm ( @@ -92,13 +104,12 @@ static void __on_cpu(int cpu, void (*function)(void *data), void *data, ipi_done = 0; ipi_function = function; ipi_data = data; + ipi_wait = wait; apic_icr_write(APIC_INT_ASSERT | APIC_DEST_PHYSICAL | APIC_DM_FIXED | IPI_VECTOR, cpu); - if (wait) { - while (!ipi_done) - ; - } + while (!ipi_done) + ; } spin_unlock(ipi_lock); } -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] qemu-kvm: Switch to upstream -enable-kvm semantics
From: Markus Armbruster arm...@redhat.com We currently enable KVM by default, and when it's not available, we print a message and fall back to TCG. Option -enable-kvm is ignored. Option -no-kvm suppresses KVM. Upstream works differently: KVM is off by default, -enable-kvm switches it on. -enable-kvm terminates the process unsuccessfully if KVM is not available. upstream qemu | default |-enable-kvm +---+--- KVM available | disabled | enabled KVM unavailable | disabled |fail qemu-kvm| default |-enable-kvm| -no-kvm +---+---+-- KVM available | enabled* | enabled | disabled KVM unavailable | disabled | disabled* | disabled * differs from upstream Users of qemu and qemu-kvm need to be aware of these differences to enable / disable use of KVM reliably. This is bothersome. Consider -enable-kvm when KVM is unavailable: If the user expects qemu-kvm behavior (fall back), but qemu fails, he'll likely be surprised and unhappy. If the user expects upstream behavior (fail), but qemu-kvm falls back to TCG, the guest runs slow as molasses, and the user will likely be confused and unhappy (unless he spots and understands the disable KVM message). Eventually, we'll sort this upstream with -accel (defaults tied to machine type). Until then, this patch reduces the difference to upstream so that most users shouldn't need to be aware of them. Make -enable-kvm behave just like in upstream: enable KVM, fail if not available. But retain current default behavior: enable KVM, fall back to TCG. qemu-kvm new| default |-enable-kvm| -no-kvm +---+---+--- KVM available | enabled* | enabled | disabled KVM unavailable | disabled |fail+ | disabled * differs from upstream + changed by this patch Bonus fix: -no-kvm -enable-kvm now enables KVM. Before, it disabled it. Signed-off-by: Markus Armbruster arm...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/vl.c b/vl.c index e3c8919..1958e01 100644 --- a/vl.c +++ b/vl.c @@ -247,7 +247,7 @@ static void *boot_set_opaque; static NotifierList exit_notifiers = NOTIFIER_LIST_INITIALIZER(exit_notifiers); -int kvm_allowed = 1; +int kvm_allowed = -1; uint32_t xen_domid; enum xen_mode xen_mode = XEN_EMULATE; @@ -2436,10 +2436,8 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_smbios: do_smbios_option(optarg); break; -#ifdef OBSOLETE_KVM_IMPL case QEMU_OPTION_enable_kvm: kvm_allowed = 1; -#endif break; case QEMU_OPTION_no_kvm: kvm_allowed = 0; @@ -2789,19 +2787,17 @@ int main(int argc, char **argv, char **envp) if (kvm_allowed) { int ret = kvm_init(smp_cpus); if (ret 0) { -#if defined(OBSOLETE_KVM_IMPL) || defined(CONFIG_NO_CPU_EMULATION) -if (!kvm_available()) { -printf(KVM not supported for this target\n); -} else { -fprintf(stderr, failed to initialize KVM: %s\n, strerror(-ret)); +if (kvm_allowed 0) { +if (!kvm_available()) { +printf(KVM not supported for this target\n); +} else { +fprintf(stderr, failed to initialize KVM: %s\n, strerror(-ret)); +} +exit(1); } -exit(1); -#endif -#ifdef CONFIG_KVM fprintf(stderr, Could not initialize KVM, will disable KVM support\n); -kvm_allowed = 0; -#endif } +kvm_allowed = ret = 0; } if (qemu_init_main_loop()) { -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: VMX: Fix incorrect cr3 with ept when clearing cr0.pg
From: Sheng Yang sh...@linux.intel.com After CR0 is changed during VMExit, the result of kvm_read_cr3() may be different. Commit d95bfcdd7cda4dfdac9588e684bc7c75794a075e KVM: Fetch guest cr3 from hardware on demand caused 32bit Windows guest blue screen when using with EPT. This patch fixes it by decache CR3 before CR0 change, for both paging to nonpaging, and nonpaging to paging switch. Signed-off-by: Sheng Yang sh...@linux.intel.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index f107315..bf89ec2 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1921,8 +1921,7 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, unsigned long cr0, struct kvm_vcpu *vcpu) { - ulong cr3; - + vmx_decache_cr3(vcpu); if (!(cr0 X86_CR0_PG)) { /* From paging/starting to nonpaging */ vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, @@ -1937,11 +1936,8 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, vmcs_read32(CPU_BASED_VM_EXEC_CONTROL) ~(CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING)); - /* Must fetch cr3 before updating cr0 */ - cr3 = kvm_read_cr3(vcpu); vcpu-arch.cr0 = cr0; vmx_set_cr4(vcpu, kvm_read_cr4(vcpu)); - vmx_set_cr3(vcpu, cr3); } if (!(cr0 X86_CR0_WP)) -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: i8259: initialize isr_ack
From: Avi Kivity a...@redhat.com isr_ack is never initialized. So, until the first PIC reset, interrupts may fail to be injected. This can cause Windows XP to fail to boot, as reported in the fallout from the fix to https://bugzilla.kernel.org/show_bug.cgi?id=21962. Reported-and-tested-by: Nicolas Prochazka prochazka.nico...@gmail.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index f628234..3cece05 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c @@ -575,6 +575,8 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm) s-pics[1].elcr_mask = 0xde; s-pics[0].pics_state = s; s-pics[1].pics_state = s; + s-pics[0].isr_ack = 0xff; + s-pics[1].isr_ack = 0xff; /* * Initialize PIO device -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] vmexit: add support for running a selected set of tests
From: Avi Kivity a...@redhat.com qemu -device testdev,chardev=log -chardev stdio,id=log \ -kernel vmexit.flat -append 'test1 test2 test3' will run test1, test2, and test3, and skip all others. Signed-off-by: Avi Kivity a...@redhat.com diff --git a/x86/vmexit.c b/x86/vmexit.c index 67746c6..31858ea 100644 --- a/x86/vmexit.c +++ b/x86/vmexit.c @@ -148,7 +148,21 @@ static void enable_nx(void *junk) wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NX_MASK); } -int main(void) +bool test_wanted(struct test *test, char *wanted[], int nwanted) +{ + int i; + + if (!nwanted) + return true; + + for (i = 0; i nwanted; ++i) + if (strcmp(wanted[i], test-name) == 0) + return true; + + return false; +} + +int main(int ac, char **av) { int i; @@ -158,7 +172,8 @@ int main(void) on_cpu(i-1, enable_nx, 0); for (i = 0; i ARRAY_SIZE(tests); ++i) - do_test(tests[i]); + if (test_wanted(tests[i], av + 1, ac - 1)) + do_test(tests[i]); return 0; } -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] lib: add strcmp() implementation
From: Avi Kivity a...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/lib/libcflat.h b/lib/libcflat.h index d4ee2e0..0c62e4c 100644 --- a/lib/libcflat.h +++ b/lib/libcflat.h @@ -42,6 +42,7 @@ extern void panic(char *fmt, ...); extern unsigned long strlen(const char *buf); extern char *strcat(char *dest, const char *src); +extern int strcmp(const char *a, const char *b); extern int printf(const char *fmt, ...); extern int vsnprintf(char *buf, int size, const char *fmt, va_list va); diff --git a/lib/string.c b/lib/string.c index 1f19f5c..9dc94a1 100644 --- a/lib/string.c +++ b/lib/string.c @@ -20,6 +20,17 @@ char *strcat(char *dest, const char *src) return dest; } +int strcmp(const char *a, const char *b) +{ +while (*a == *b) { + if (*a == '\0') { + break; + } + ++a, ++b; +} +return *a - *b; +} + void *memset(void *s, int c, size_t n) { size_t i; -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] vmexit: add ple stress test
From: Avi Kivity a...@redhat.com This test round-robins executions among all cpus. If overcommitted, it will execute at the rate the host switches vcpu contexts. Signed-off-by: Avi Kivity a...@redhat.com diff --git a/x86/vmexit.c b/x86/vmexit.c index 31858ea..875caa3 100644 --- a/x86/vmexit.c +++ b/x86/vmexit.c @@ -12,6 +12,8 @@ static unsigned int inl(unsigned short port) #define GOAL (1ull 30) +static int nr_cpus; + #ifdef __x86_64__ # define R r #else @@ -79,6 +81,27 @@ static void inl_pmtimer(void) inl(0xb008); } +static void ple_round_robin(void) +{ + struct counter { + volatile int n1; + int n2; + } __attribute__((aligned(64))); + static struct counter counters[64] = { { -1, 0 } }; + int me = smp_id(); + int you; + volatile struct counter *p = counters[me]; + + while (p-n1 == p-n2) + asm volatile (pause); + + p-n2 = p-n1; + you = me + 1; + if (you == nr_cpus) + you = 0; + ++counters[you].n1; +} + static struct test { void (*func)(void); const char *name; @@ -94,6 +117,7 @@ static struct test { { inl_pmtimer, inl_from_pmtimer, .parallel = 1, }, { ipi, ipi, is_smp, .parallel = 0, }, { ipi_halt, ipi+halt, is_smp, .parallel = 0, }, + { ple_round_robin, ple-round-robin, .parallel = 1 }, }; unsigned iterations; @@ -167,6 +191,7 @@ int main(int ac, char **av) int i; smp_init(); + nr_cpus = cpu_count(); for (i = cpu_count(); i 0; i--) on_cpu(i-1, enable_nx, 0); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: x86: fix CR8 handling
From: Andre Przywara andre.przyw...@amd.com The handling of CR8 writes in KVM is currently somewhat cumbersome. This patch makes it look like the other CR register handlers and fixes a possible issue in VMX, where the RIP would be incremented despite an injected #GP. Signed-off-by: Andre Przywara andre.przyw...@amd.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 4461429..cb5cad2 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -661,7 +661,7 @@ int kvm_task_switch(struct kvm_vcpu *vcpu, u16 tss_selector, int reason, int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4); -void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8); +int kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8); int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val); int kvm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *val); unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu); diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 24b4373..06a0892 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2676,16 +2676,17 @@ static int cr0_write_interception(struct vcpu_svm *svm) static int cr8_write_interception(struct vcpu_svm *svm) { struct kvm_run *kvm_run = svm-vcpu.run; + int r; u8 cr8_prev = kvm_get_cr8(svm-vcpu); /* instruction emulation calls kvm_set_cr8() */ - emulate_instruction(svm-vcpu, 0, 0, 0); + r = emulate_instruction(svm-vcpu, 0, 0, 0); if (irqchip_in_kernel(svm-vcpu.kvm)) { clr_cr_intercept(svm, INTERCEPT_CR8_WRITE); - return 1; + return r == EMULATE_DONE; } if (cr8_prev = kvm_get_cr8(svm-vcpu)) - return 1; + return r == EMULATE_DONE; kvm_run-exit_reason = KVM_EXIT_SET_TPR; return 0; } diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index c195260..8e87bae 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3185,8 +3185,8 @@ static int handle_cr(struct kvm_vcpu *vcpu) case 8: { u8 cr8_prev = kvm_get_cr8(vcpu); u8 cr8 = kvm_register_read(vcpu, reg); - kvm_set_cr8(vcpu, cr8); - skip_emulated_instruction(vcpu); + err = kvm_set_cr8(vcpu, cr8); + complete_insn_gp(vcpu, err); if (irqchip_in_kernel(vcpu-kvm)) return 1; if (cr8_prev = cr8) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f569da8..2dbf68c 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -662,7 +662,7 @@ int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) } EXPORT_SYMBOL_GPL(kvm_set_cr3); -int __kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) +int kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) { if (cr8 CR8_RESERVED_BITS) return 1; @@ -672,12 +672,6 @@ int __kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) vcpu-arch.cr8 = cr8; return 0; } - -void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) -{ - if (__kvm_set_cr8(vcpu, cr8)) - kvm_inject_gp(vcpu, 0); -} EXPORT_SYMBOL_GPL(kvm_set_cr8); unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu) @@ -4104,7 +4098,7 @@ static int emulator_set_cr(int cr, unsigned long val, struct kvm_vcpu *vcpu) res = kvm_set_cr4(vcpu, mk_cr_64(kvm_read_cr4(vcpu), val)); break; case 8: - res = __kvm_set_cr8(vcpu, val 0xfUL); + res = kvm_set_cr8(vcpu, val); break; default: vcpu_printf(vcpu, %s: unexpected cr %u\n, __func__, cr); @@ -5381,8 +5375,12 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) } /* re-sync apic's tpr */ - if (!irqchip_in_kernel(vcpu-kvm)) - kvm_set_cr8(vcpu, kvm_run-cr8); + if (!irqchip_in_kernel(vcpu-kvm)) { + if (kvm_set_cr8(vcpu, kvm_run-cr8) != 0) { + r = -EINVAL; + goto out; + } + } if (vcpu-arch.pio.count || vcpu-mmio_needed) { if (vcpu-mmio_needed) { -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: move complete_insn_gp() into x86.c
From: Andre Przywara andre.przyw...@amd.com move the complete_insn_gp() helper function out of the VMX part into the generic x86 part to make it usable by SVM. Signed-off-by: Andre Przywara andre.przyw...@amd.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index cb5cad2..cd4a990 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -828,4 +828,6 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu); extern bool kvm_find_async_pf_gfn(struct kvm_vcpu *vcpu, gfn_t gfn); +void kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err); + #endif /* _ASM_X86_KVM_HOST_H */ diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 8e87bae..fd8ffde 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -3147,14 +3147,6 @@ vmx_patch_hypercall(struct kvm_vcpu *vcpu, unsigned char *hypercall) hypercall[2] = 0xc1; } -static void complete_insn_gp(struct kvm_vcpu *vcpu, int err) -{ - if (err) - kvm_inject_gp(vcpu, 0); - else - skip_emulated_instruction(vcpu); -} - static int handle_cr(struct kvm_vcpu *vcpu) { unsigned long exit_qualification, val; @@ -3172,21 +3164,21 @@ static int handle_cr(struct kvm_vcpu *vcpu) switch (cr) { case 0: err = kvm_set_cr0(vcpu, val); - complete_insn_gp(vcpu, err); + kvm_complete_insn_gp(vcpu, err); return 1; case 3: err = kvm_set_cr3(vcpu, val); - complete_insn_gp(vcpu, err); + kvm_complete_insn_gp(vcpu, err); return 1; case 4: err = kvm_set_cr4(vcpu, val); - complete_insn_gp(vcpu, err); + kvm_complete_insn_gp(vcpu, err); return 1; case 8: { u8 cr8_prev = kvm_get_cr8(vcpu); u8 cr8 = kvm_register_read(vcpu, reg); err = kvm_set_cr8(vcpu, cr8); - complete_insn_gp(vcpu, err); + kvm_complete_insn_gp(vcpu, err); if (irqchip_in_kernel(vcpu-kvm)) return 1; if (cr8_prev = cr8) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 2dbf68c..1d54cb7 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -334,6 +334,15 @@ void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned nr) } EXPORT_SYMBOL_GPL(kvm_requeue_exception); +void kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err) +{ + if (err) + kvm_inject_gp(vcpu, 0); + else + kvm_x86_ops-skip_emulated_instruction(vcpu); +} +EXPORT_SYMBOL_GPL(kvm_complete_insn_gp); + void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault) { ++vcpu-stat.pf_guest; -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: cleanup emulate_instruction
From: Andre Przywara andre.przyw...@amd.com emulate_instruction had many callers, but only one used all parameters. One parameter was unused, another one is now hidden by a wrapper function (required for a future addition anyway), so most callers use now a shorter parameter list. Signed-off-by: Andre Przywara andre.przyw...@amd.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index cd4a990..de00b60 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -634,8 +634,15 @@ enum emulation_result { #define EMULTYPE_NO_DECODE (1 0) #define EMULTYPE_TRAP_UD (1 1) #define EMULTYPE_SKIP (1 2) -int emulate_instruction(struct kvm_vcpu *vcpu, - unsigned long cr2, u16 error_code, int emulation_type); +int x86_emulate_instruction(struct kvm_vcpu *vcpu, + unsigned long cr2, int emulation_type); + +static inline int emulate_instruction(struct kvm_vcpu *vcpu, + int emulation_type) +{ + return x86_emulate_instruction(vcpu, 0, emulation_type); +} + void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index c3853d5..75334de 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3347,7 +3347,7 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code) if (r) goto out; - er = emulate_instruction(vcpu, cr2, error_code, 0); + er = x86_emulate_instruction(vcpu, cr2, 0); switch (er) { case EMULATE_DONE: diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 06a0892..d49d73c 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -475,7 +475,7 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) svm-next_rip = svm-vmcb-control.next_rip; if (!svm-next_rip) { - if (emulate_instruction(vcpu, 0, 0, EMULTYPE_SKIP) != + if (emulate_instruction(vcpu, EMULTYPE_SKIP) != EMULATE_DONE) printk(KERN_DEBUG %s: NOP\n, __func__); return; @@ -1586,7 +1586,7 @@ static int ud_interception(struct vcpu_svm *svm) { int er; - er = emulate_instruction(svm-vcpu, 0, 0, EMULTYPE_TRAP_UD); + er = emulate_instruction(svm-vcpu, EMULTYPE_TRAP_UD); if (er != EMULATE_DONE) kvm_queue_exception(svm-vcpu, UD_VECTOR); return 1; @@ -1703,7 +1703,7 @@ static int io_interception(struct vcpu_svm *svm) string = (io_info SVM_IOIO_STR_MASK) != 0; in = (io_info SVM_IOIO_TYPE_MASK) != 0; if (string || in) - return emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE; + return emulate_instruction(vcpu, 0) == EMULATE_DONE; port = io_info 16; size = (io_info SVM_IOIO_SIZE_MASK) SVM_IOIO_SIZE_SHIFT; @@ -2648,12 +2648,12 @@ static int iret_interception(struct vcpu_svm *svm) static int invlpg_interception(struct vcpu_svm *svm) { - return emulate_instruction(svm-vcpu, 0, 0, 0) == EMULATE_DONE; + return emulate_instruction(svm-vcpu, 0) == EMULATE_DONE; } static int emulate_on_interception(struct vcpu_svm *svm) { - return emulate_instruction(svm-vcpu, 0, 0, 0) == EMULATE_DONE; + return emulate_instruction(svm-vcpu, 0) == EMULATE_DONE; } static int cr0_write_interception(struct vcpu_svm *svm) @@ -2661,7 +2661,7 @@ static int cr0_write_interception(struct vcpu_svm *svm) struct kvm_vcpu *vcpu = svm-vcpu; int r; - r = emulate_instruction(svm-vcpu, 0, 0, 0); + r = emulate_instruction(svm-vcpu, 0); if (svm-nested.vmexit_rip) { kvm_register_write(vcpu, VCPU_REGS_RIP, svm-nested.vmexit_rip); @@ -2680,7 +2680,7 @@ static int cr8_write_interception(struct vcpu_svm *svm) u8 cr8_prev = kvm_get_cr8(svm-vcpu); /* instruction emulation calls kvm_set_cr8() */ - r = emulate_instruction(svm-vcpu, 0, 0, 0); + r = emulate_instruction(svm-vcpu, 0); if (irqchip_in_kernel(svm-vcpu.kvm)) { clr_cr_intercept(svm, INTERCEPT_CR8_WRITE); return r == EMULATE_DONE; diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index fd8ffde..f3c60fb 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2939,7 +2939,7 @@ static int handle_rmode_exception(struct kvm_vcpu *vcpu, * Cause the #SS fault with 0 error code in VM86 mode. */ if (((vec == GP_VECTOR) || (vec == SS_VECTOR)) err_code == 0) - if (emulate_instruction(vcpu, 0, 0, 0) == EMULATE_DONE) + if (emulate_instruction(vcpu, 0) == EMULATE_DONE) return 1; /* * Forward all other
[COMMIT master] KVM: SVM: add new SVM feature bit names
From: Andre Przywara andre.przyw...@amd.com the recent APM Vol.2 and the recent AMD CPUID specification describe new CPUID features bits for SVM. Name them here for later usage. Signed-off-by: Andre Przywara andre.przyw...@amd.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index d49d73c..e2ea75f 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -51,6 +51,10 @@ MODULE_LICENSE(GPL); #define SVM_FEATURE_LBRV (1 1) #define SVM_FEATURE_SVML (1 2) #define SVM_FEATURE_NRIP (1 3) +#define SVM_FEATURE_TSC_RATE (1 4) +#define SVM_FEATURE_VMCB_CLEAN (1 5) +#define SVM_FEATURE_FLUSH_ASID (1 6) +#define SVM_FEATURE_DECODE_ASSIST (1 7) #define SVM_FEATURE_PAUSE_FILTER (1 10) #define NESTED_EXIT_HOST 0 /* Exit handled on host level */ -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: SVM: enhance mov DR intercept handler
From: Andre Przywara andre.przyw...@amd.com Newer SVM implementations provide the GPR number in the VMCB, so that the emulation path is no longer necesarry to handle debug register access intercepts. Implement the handling in svm.c and use it when the info is provided. Signed-off-by: Andre Przywara andre.przyw...@amd.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index b944a0f..28b6fe8 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2745,6 +2745,30 @@ static int cr0_write_interception(struct vcpu_svm *svm) return r; } +static int dr_interception(struct vcpu_svm *svm) +{ + int reg, dr; + unsigned long val; + int err; + + if (!boot_cpu_has(X86_FEATURE_DECODEASSISTS)) + return emulate_on_interception(svm); + + reg = svm-vmcb-control.exit_info_1 SVM_EXITINFO_REG_MASK; + dr = svm-vmcb-control.exit_code - SVM_EXIT_READ_DR0; + + if (dr = 16) { /* mov to DRn */ + val = kvm_register_read(svm-vcpu, reg); + kvm_set_dr(svm-vcpu, dr - 16, val); + } else { + err = kvm_get_dr(svm-vcpu, dr, val); + if (!err) + kvm_register_write(svm-vcpu, reg, val); + } + + return 1; +} + static int cr8_write_interception(struct vcpu_svm *svm) { struct kvm_run *kvm_run = svm-vcpu.run; @@ -3010,22 +3034,22 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { [SVM_EXIT_WRITE_CR3]= cr_interception, [SVM_EXIT_WRITE_CR4]= cr_interception, [SVM_EXIT_WRITE_CR8]= cr8_write_interception, - [SVM_EXIT_READ_DR0] = emulate_on_interception, - [SVM_EXIT_READ_DR1] = emulate_on_interception, - [SVM_EXIT_READ_DR2] = emulate_on_interception, - [SVM_EXIT_READ_DR3] = emulate_on_interception, - [SVM_EXIT_READ_DR4] = emulate_on_interception, - [SVM_EXIT_READ_DR5] = emulate_on_interception, - [SVM_EXIT_READ_DR6] = emulate_on_interception, - [SVM_EXIT_READ_DR7] = emulate_on_interception, - [SVM_EXIT_WRITE_DR0]= emulate_on_interception, - [SVM_EXIT_WRITE_DR1]= emulate_on_interception, - [SVM_EXIT_WRITE_DR2]= emulate_on_interception, - [SVM_EXIT_WRITE_DR3]= emulate_on_interception, - [SVM_EXIT_WRITE_DR4]= emulate_on_interception, - [SVM_EXIT_WRITE_DR5]= emulate_on_interception, - [SVM_EXIT_WRITE_DR6]= emulate_on_interception, - [SVM_EXIT_WRITE_DR7]= emulate_on_interception, + [SVM_EXIT_READ_DR0] = dr_interception, + [SVM_EXIT_READ_DR1] = dr_interception, + [SVM_EXIT_READ_DR2] = dr_interception, + [SVM_EXIT_READ_DR3] = dr_interception, + [SVM_EXIT_READ_DR4] = dr_interception, + [SVM_EXIT_READ_DR5] = dr_interception, + [SVM_EXIT_READ_DR6] = dr_interception, + [SVM_EXIT_READ_DR7] = dr_interception, + [SVM_EXIT_WRITE_DR0]= dr_interception, + [SVM_EXIT_WRITE_DR1]= dr_interception, + [SVM_EXIT_WRITE_DR2]= dr_interception, + [SVM_EXIT_WRITE_DR3]= dr_interception, + [SVM_EXIT_WRITE_DR4]= dr_interception, + [SVM_EXIT_WRITE_DR5]= dr_interception, + [SVM_EXIT_WRITE_DR6]= dr_interception, + [SVM_EXIT_WRITE_DR7]= dr_interception, [SVM_EXIT_EXCP_BASE + DB_VECTOR]= db_interception, [SVM_EXIT_EXCP_BASE + BP_VECTOR]= bp_interception, [SVM_EXIT_EXCP_BASE + UD_VECTOR]= ud_interception, -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: SVM: enhance MOV CR intercept handler
From: Andre Przywara andre.przyw...@amd.com Newer SVM implementations provide the GPR number in the VMCB, so that the emulation path is no longer necesarry to handle CR register access intercepts. Implement the handling in svm.c and use it when the info is provided. Signed-off-by: Andre Przywara andre.przyw...@amd.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index f7087bf..f0ffb81 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -260,6 +260,8 @@ struct __attribute__ ((__packed__)) vmcb { #define SVM_EXITINFOSHIFT_TS_REASON_JMP 38 #define SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE 44 +#define SVM_EXITINFO_REG_MASK 0x0F + #defineSVM_EXIT_READ_CR0 0x000 #defineSVM_EXIT_READ_CR3 0x003 #defineSVM_EXIT_READ_CR4 0x004 diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index e2ea75f..b944a0f 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -2660,12 +2660,80 @@ static int emulate_on_interception(struct vcpu_svm *svm) return emulate_instruction(svm-vcpu, 0) == EMULATE_DONE; } +#define CR_VALID (1ULL 63) + +static int cr_interception(struct vcpu_svm *svm) +{ + int reg, cr; + unsigned long val; + int err; + + if (!static_cpu_has(X86_FEATURE_DECODEASSISTS)) + return emulate_on_interception(svm); + + if (unlikely((svm-vmcb-control.exit_info_1 CR_VALID) == 0)) + return emulate_on_interception(svm); + + reg = svm-vmcb-control.exit_info_1 SVM_EXITINFO_REG_MASK; + cr = svm-vmcb-control.exit_code - SVM_EXIT_READ_CR0; + + err = 0; + if (cr = 16) { /* mov to cr */ + cr -= 16; + val = kvm_register_read(svm-vcpu, reg); + switch (cr) { + case 0: + err = kvm_set_cr0(svm-vcpu, val); + break; + case 3: + err = kvm_set_cr3(svm-vcpu, val); + break; + case 4: + err = kvm_set_cr4(svm-vcpu, val); + break; + case 8: + err = kvm_set_cr8(svm-vcpu, val); + break; + default: + WARN(1, unhandled write to CR%d, cr); + kvm_queue_exception(svm-vcpu, UD_VECTOR); + return 1; + } + } else { /* mov from cr */ + switch (cr) { + case 0: + val = kvm_read_cr0(svm-vcpu); + break; + case 2: + val = svm-vcpu.arch.cr2; + break; + case 3: + val = svm-vcpu.arch.cr3; + break; + case 4: + val = kvm_read_cr4(svm-vcpu); + break; + case 8: + val = kvm_get_cr8(svm-vcpu); + break; + default: + WARN(1, unhandled read from CR%d, cr); + kvm_queue_exception(svm-vcpu, UD_VECTOR); + return 1; + } + kvm_register_write(svm-vcpu, reg, val); + } + kvm_complete_insn_gp(svm-vcpu, err); + + return 1; +} + static int cr0_write_interception(struct vcpu_svm *svm) { struct kvm_vcpu *vcpu = svm-vcpu; int r; - r = emulate_instruction(svm-vcpu, 0); + r = cr_interception(svm); if (svm-nested.vmexit_rip) { kvm_register_write(vcpu, VCPU_REGS_RIP, svm-nested.vmexit_rip); @@ -2674,7 +2742,7 @@ static int cr0_write_interception(struct vcpu_svm *svm) svm-nested.vmexit_rip = 0; } - return r == EMULATE_DONE; + return r; } static int cr8_write_interception(struct vcpu_svm *svm) @@ -2684,13 +2752,13 @@ static int cr8_write_interception(struct vcpu_svm *svm) u8 cr8_prev = kvm_get_cr8(svm-vcpu); /* instruction emulation calls kvm_set_cr8() */ - r = emulate_instruction(svm-vcpu, 0); + r = cr_interception(svm); if (irqchip_in_kernel(svm-vcpu.kvm)) { clr_cr_intercept(svm, INTERCEPT_CR8_WRITE); - return r == EMULATE_DONE; + return r; } if (cr8_prev = kvm_get_cr8(svm-vcpu)) - return r == EMULATE_DONE; + return r; kvm_run-exit_reason = KVM_EXIT_SET_TPR; return 0; } @@ -2933,14 +3001,14 @@ static int pause_interception(struct vcpu_svm *svm) } static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { - [SVM_EXIT_READ_CR0] = emulate_on_interception, - [SVM_EXIT_READ_CR3] = emulate_on_interception, - [SVM_EXIT_READ_CR4] =
[COMMIT master] KVM: SVM: copy instruction bytes from VMCB
From: Andre Przywara andre.przyw...@amd.com In case of a nested page fault or an intercepted #PF newer SVM implementations provide a copy of the faulting instruction bytes in the VMCB. Use these bytes to feed the instruction emulator and avoid the costly guest instruction fetch in this case. Signed-off-by: Andre Przywara andre.przyw...@amd.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index bf70ece..8e37deb 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -265,7 +265,7 @@ struct x86_emulate_ctxt { #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64 #endif -int x86_decode_insn(struct x86_emulate_ctxt *ctxt); +int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len); #define EMULATION_FAILED -1 #define EMULATION_OK 0 #define EMULATION_RESTART 1 diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index de00b60..6268f6c 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -634,13 +634,13 @@ enum emulation_result { #define EMULTYPE_NO_DECODE (1 0) #define EMULTYPE_TRAP_UD (1 1) #define EMULTYPE_SKIP (1 2) -int x86_emulate_instruction(struct kvm_vcpu *vcpu, - unsigned long cr2, int emulation_type); +int x86_emulate_instruction(struct kvm_vcpu *vcpu, unsigned long cr2, + int emulation_type, void *insn, int insn_len); static inline int emulate_instruction(struct kvm_vcpu *vcpu, int emulation_type) { - return x86_emulate_instruction(vcpu, 0, emulation_type); + return x86_emulate_instruction(vcpu, 0, emulation_type, NULL, 0); } void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address); @@ -721,7 +721,8 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu); int kvm_fix_hypercall(struct kvm_vcpu *vcpu); -int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code); +int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code, + void *insn, int insn_len); void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva); void kvm_enable_tdp(void); diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index f0ffb81..f2b83bc 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -83,7 +83,9 @@ struct __attribute__ ((__packed__)) vmcb_control_area { u32 clean; u32 reserved_5; u64 next_rip; - u8 reserved_6[816]; + u8 insn_len; + u8 insn_bytes[15]; + u8 reserved_6[800]; }; diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 6366735..02a0041 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -2610,7 +2610,7 @@ done: } int -x86_decode_insn(struct x86_emulate_ctxt *ctxt) +x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len) { struct x86_emulate_ops *ops = ctxt-ops; struct decode_cache *c = ctxt-decode; @@ -2621,7 +2621,10 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt) struct operand memop = { .type = OP_NONE }; c-eip = ctxt-eip; - c-fetch.start = c-fetch.end = c-eip; + c-fetch.start = c-eip; + c-fetch.end = c-fetch.start + insn_len; + if (insn_len 0) + memcpy(c-fetch.data, insn, insn_len); ctxt-cs_base = seg_base(ctxt, ops, VCPU_SREG_CS); switch (mode) { diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 75334de..397a98f 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3329,7 +3329,8 @@ void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu) } } -int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code) +int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code, + void *insn, int insn_len) { int r; enum emulation_result er; @@ -3347,7 +3348,7 @@ int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t cr2, u32 error_code) if (r) goto out; - er = x86_emulate_instruction(vcpu, cr2, 0); + er = x86_emulate_instruction(vcpu, cr2, 0, insn, insn_len); switch (er) { case EMULATE_DONE: diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 7b7e1ab..c9d711f 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1527,7 +1527,9 @@ static int pf_interception(struct vcpu_svm *svm) trace_kvm_page_fault(fault_address, error_code); if (!npt_enabled kvm_event_needs_reinjection(svm-vcpu)) kvm_mmu_unprotect_page_virt(svm-vcpu, fault_address); - r = kvm_mmu_page_fault(svm-vcpu, fault_address, error_code); + r = kvm_mmu_page_fault(svm-vcpu, fault_address, error_code, + svm-vmcb-control.insn_bytes, + svm-vmcb-control.insn_len);
[COMMIT master] KVM: VMX: Optimize atomic EFER load
From: Avi Kivity a...@redhat.com When NX is enabled on the host but not on the guest, we use the entry/exit msr load facility, which is slow. Optimize it to use entry/exit efer load, which is ~1200 cycles faster. Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 736f839..a713c69 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -191,6 +191,8 @@ static unsigned long *vmx_io_bitmap_b; static unsigned long *vmx_msr_bitmap_legacy; static unsigned long *vmx_msr_bitmap_longmode; +static bool cpu_has_load_ia32_efer; + static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS); static DEFINE_SPINLOCK(vmx_vpid_lock); @@ -664,6 +666,12 @@ static void clear_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr) unsigned i; struct msr_autoload *m = vmx-msr_autoload; + if (msr == MSR_EFER cpu_has_load_ia32_efer) { + vmcs_clear_bits(VM_ENTRY_CONTROLS, VM_ENTRY_LOAD_IA32_EFER); + vmcs_clear_bits(VM_EXIT_CONTROLS, VM_EXIT_LOAD_IA32_EFER); + return; + } + for (i = 0; i m-nr; ++i) if (m-guest[i].index == msr) break; @@ -683,6 +691,14 @@ static void add_atomic_switch_msr(struct vcpu_vmx *vmx, unsigned msr, unsigned i; struct msr_autoload *m = vmx-msr_autoload; + if (msr == MSR_EFER cpu_has_load_ia32_efer) { + vmcs_write64(GUEST_IA32_EFER, guest_val); + vmcs_write64(HOST_IA32_EFER, host_val); + vmcs_set_bits(VM_ENTRY_CONTROLS, VM_ENTRY_LOAD_IA32_EFER); + vmcs_set_bits(VM_EXIT_CONTROLS, VM_EXIT_LOAD_IA32_EFER); + return; + } + for (i = 0; i m-nr; ++i) if (m-guest[i].index == msr) break; @@ -1418,6 +1434,14 @@ static __init int adjust_vmx_controls(u32 ctl_min, u32 ctl_opt, return 0; } +static __init bool allow_1_setting(u32 msr, u32 ctl) +{ + u32 vmx_msr_low, vmx_msr_high; + + rdmsr(msr, vmx_msr_low, vmx_msr_high); + return vmx_msr_high ctl; +} + static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) { u32 vmx_msr_low, vmx_msr_high; @@ -1532,6 +1556,12 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) vmcs_conf-vmexit_ctrl = _vmexit_control; vmcs_conf-vmentry_ctrl= _vmentry_control; + cpu_has_load_ia32_efer = + allow_1_setting(MSR_IA32_VMX_ENTRY_CTLS, + VM_ENTRY_LOAD_IA32_EFER) +allow_1_setting(MSR_IA32_VMX_EXIT_CTLS, + VM_EXIT_LOAD_IA32_EFER); + return 0; } -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: MMU: only write protect mappings at pagetable level
From: Marcelo Tosatti mtosa...@redhat.com If a pagetable contains a writeable large spte, all of its sptes will be write protected, including non-leaf ones, leading to endless pagefaults. Do not write protect pages above PT_PAGE_TABLE_LEVEL, as the spte fault paths assume non-leaf sptes are writable. Tested-by: Alex Williamson alex.william...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 113cfd6..612b565 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3444,6 +3444,9 @@ void kvm_mmu_slot_remove_write_access(struct kvm *kvm, int slot) if (!test_bit(slot, sp-slot_bitmap)) continue; + if (sp-role.level != PT_PAGE_TABLE_LEVEL) + continue; + pt = sp-spt; for (i = 0; i PT64_ENT_PER_PAGE; ++i) /* avoid RMW */ -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: SVM: Load %fs early on vmexit path, on i386
From: Avi Kivity a...@redhat.com Fixes an oops due to the per-cpu area being referenced with the guest's %fs. Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index c9d711f..af4b911 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1148,8 +1148,8 @@ static void svm_vcpu_put(struct kvm_vcpu *vcpu) ++vcpu-stat.host_state_reload; kvm_load_ldt(svm-host.ldt); - loadsegment(fs, svm-host.fs); #ifdef CONFIG_X86_64 + loadsegment(fs, svm-host.fs); load_gs_index(svm-host.gs); wrmsrl(MSR_KERNEL_GS_BASE, current-thread.gs); #else @@ -3633,6 +3633,8 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) #ifdef CONFIG_X86_64 wrmsrl(MSR_GS_BASE, svm-host.gs_base); +#else + loadsegment(fs, svm-host.fs); #endif reload_tss(vcpu); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: VMX: Correct asm constraint in vmcs_load()/vmcs_clear()
From: Avi Kivity a...@redhat.com 'error' is byte sized, so use a byte register constraint. Acked-by: Randy Dunlap randy.dun...@oracle.com Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a713c69..67c0852 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -477,7 +477,7 @@ static void vmcs_clear(struct vmcs *vmcs) u8 error; asm volatile (__ex(ASM_VMX_VMCLEAR_RAX) ; setna %0 - : =g(error) : a(phys_addr), m(phys_addr) + : =qm(error) : a(phys_addr), m(phys_addr) : cc, memory); if (error) printk(KERN_ERR kvm: vmclear fail: %p/%llx\n, @@ -490,7 +490,7 @@ static void vmcs_load(struct vmcs *vmcs) u8 error; asm volatile (__ex(ASM_VMX_VMPTRLD_RAX) ; setna %0 - : =g(error) : a(phys_addr), m(phys_addr) + : =qm(error) : a(phys_addr), m(phys_addr) : cc, memory); if (error) printk(KERN_ERR kvm: vmptrld %p/%llx fail\n, -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: Fetch guest cr3 from hardware on demand
From: Avi Kivity a...@redhat.com Instead of syncing the guest cr3 every exit, which is expensince on vmx with ept enabled, sync it only on demand. Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 6268f6c..95f026b 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -117,6 +117,7 @@ enum kvm_reg { enum kvm_reg_ex { VCPU_EXREG_PDPTR = NR_VCPU_REGS, + VCPU_EXREG_CR3, }; enum { @@ -533,6 +534,7 @@ struct kvm_x86_ops { struct kvm_segment *var, int seg); void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); void (*decache_cr0_guest_bits)(struct kvm_vcpu *vcpu); + void (*decache_cr3)(struct kvm_vcpu *vcpu); void (*decache_cr4_guest_bits)(struct kvm_vcpu *vcpu); void (*set_cr0)(struct kvm_vcpu *vcpu, unsigned long cr0); void (*set_cr3)(struct kvm_vcpu *vcpu, unsigned long cr3); diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h index a6bf8db..3377d53 100644 --- a/arch/x86/kvm/kvm_cache_regs.h +++ b/arch/x86/kvm/kvm_cache_regs.h @@ -75,6 +75,8 @@ static inline ulong kvm_read_cr4_bits(struct kvm_vcpu *vcpu, ulong mask) static inline ulong kvm_read_cr3(struct kvm_vcpu *vcpu) { + if (!test_bit(VCPU_EXREG_CR3, (ulong *)vcpu-arch.regs_avail)) + kvm_x86_ops-decache_cr3(vcpu); return vcpu-arch.cr3; } diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index a7b04c0..25bd1bc 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1327,6 +1327,10 @@ static void svm_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) { } +static void svm_decache_cr3(struct kvm_vcpu *vcpu) +{ +} + static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) { } @@ -3871,6 +3875,7 @@ static struct kvm_x86_ops svm_x86_ops = { .get_cpl = svm_get_cpl, .get_cs_db_l_bits = kvm_get_cs_db_l_bits, .decache_cr0_guest_bits = svm_decache_cr0_guest_bits, + .decache_cr3 = svm_decache_cr3, .decache_cr4_guest_bits = svm_decache_cr4_guest_bits, .set_cr0 = svm_set_cr0, .set_cr3 = svm_set_cr3, diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 141956e..2260783 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -180,6 +180,7 @@ static int init_rmode(struct kvm *kvm); static u64 construct_eptp(unsigned long root_hpa); static void kvm_cpu_vmxon(u64 addr); static void kvm_cpu_vmxoff(void); +static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3); static DEFINE_PER_CPU(struct vmcs *, vmxarea); static DEFINE_PER_CPU(struct vmcs *, current_vmcs); @@ -1866,6 +1867,13 @@ static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) vcpu-arch.cr0 |= vmcs_readl(GUEST_CR0) cr0_guest_owned_bits; } +static void vmx_decache_cr3(struct kvm_vcpu *vcpu) +{ + if (enable_ept is_paging(vcpu)) + vcpu-arch.cr3 = vmcs_readl(GUEST_CR3); + __set_bit(VCPU_EXREG_CR3, (ulong *)vcpu-arch.regs_avail); +} + static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) { ulong cr4_guest_owned_bits = vcpu-arch.cr4_guest_owned_bits; @@ -1909,6 +1917,8 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, unsigned long cr0, struct kvm_vcpu *vcpu) { + ulong cr3; + if (!(cr0 X86_CR0_PG)) { /* From paging/starting to nonpaging */ vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, @@ -1923,8 +1933,11 @@ static void ept_update_paging_mode_cr0(unsigned long *hw_cr0, vmcs_read32(CPU_BASED_VM_EXEC_CONTROL) ~(CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING)); + /* Must fetch cr3 before updating cr0 */ + cr3 = kvm_read_cr3(vcpu); vcpu-arch.cr0 = cr0; vmx_set_cr4(vcpu, kvm_read_cr4(vcpu)); + vmx_set_cr3(vcpu, cr3); } if (!(cr0 X86_CR0_WP)) @@ -3756,11 +3769,6 @@ static int vmx_handle_exit(struct kvm_vcpu *vcpu) if (vmx-emulation_required emulate_invalid_guest_state) return handle_invalid_guest_state(vcpu); - /* Access CR3 don't cause VMExit in paging mode, so we need -* to sync with guest real CR3. */ - if (enable_ept is_paging(vcpu)) - vcpu-arch.cr3 = vmcs_readl(GUEST_CR3); - if (exit_reason VMX_EXIT_REASONS_FAILED_VMENTRY) { vcpu-run-exit_reason = KVM_EXIT_FAIL_ENTRY; vcpu-run-fail_entry.hardware_entry_failure_reason @@ -4077,7 +4085,8 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu) ); vcpu-arch.regs_avail = ~((1 VCPU_REGS_RIP) | (1 VCPU_REGS_RSP) - | (1 VCPU_EXREG_PDPTR)); +
[COMMIT master] KVM: MMU: handle 'map_writable' in set_spte() function
From: Xiao Guangrong xiaoguangr...@cn.fujitsu.com Move the operation of 'writable' to set_spte() to clean up code [avi: remove unneeded booleanification] Signed-off-by: Xiao Guangrong xiaoguangr...@cn.fujitsu.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index afd17f2..e491653 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1983,6 +1983,8 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, if (host_writable) spte |= SPTE_HOST_WRITEABLE; + else + pte_access = ~ACC_WRITE_MASK; spte |= (u64)pfn PAGE_SHIFT; @@ -,8 +2224,6 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, if (iterator.level == level) { unsigned pte_access = ACC_ALL; - if (!map_writable) - pte_access = ~ACC_WRITE_MASK; mmu_set_spte(vcpu, iterator.sptep, ACC_ALL, pte_access, 0, write, 1, pt_write, level, gfn, pfn, prefault, map_writable); diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 5ca9426..53210f1 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -511,9 +511,6 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, link_shadow_page(it.sptep, sp); } - if (!map_writable) - access = ~ACC_WRITE_MASK; - mmu_set_spte(vcpu, it.sptep, access, gw-pte_access access, user_fault, write_fault, dirty, ptwrite, it.level, gw-gfn, pfn, prefault, map_writable); @@ -809,12 +806,8 @@ static int FNAME(sync_page)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) nr_present++; pte_access = sp-role.access FNAME(gpte_access)(vcpu, gpte); - if (!(sp-spt[i] SPTE_HOST_WRITEABLE)) { - pte_access = ~ACC_WRITE_MASK; - host_writable = 0; - } else { - host_writable = 1; - } + host_writable = sp-spt[i] SPTE_HOST_WRITEABLE; + set_spte(vcpu, sp-spt[i], pte_access, 0, 0, is_dirty_gpte(gpte), PT_PAGE_TABLE_LEVEL, gfn, spte_to_pfn(sp-spt[i]), true, false, -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: Replace reads of vcpu-arch.cr3 by an accessor
From: Avi Kivity a...@redhat.com This allows us to keep cr3 in the VMCS, later on. Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/kvm/kvm_cache_regs.h b/arch/x86/kvm/kvm_cache_regs.h index 95ac3af..a6bf8db 100644 --- a/arch/x86/kvm/kvm_cache_regs.h +++ b/arch/x86/kvm/kvm_cache_regs.h @@ -73,6 +73,11 @@ static inline ulong kvm_read_cr4_bits(struct kvm_vcpu *vcpu, ulong mask) return vcpu-arch.cr4 mask; } +static inline ulong kvm_read_cr3(struct kvm_vcpu *vcpu) +{ + return vcpu-arch.cr3; +} + static inline ulong kvm_read_cr4(struct kvm_vcpu *vcpu) { return kvm_read_cr4_bits(vcpu, ~0UL); diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 612b565..43bd5e3 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2726,13 +2726,13 @@ void kvm_mmu_flush_tlb(struct kvm_vcpu *vcpu) static void paging_new_cr3(struct kvm_vcpu *vcpu) { - pgprintk(%s: cr3 %lx\n, __func__, vcpu-arch.cr3); + pgprintk(%s: cr3 %lx\n, __func__, kvm_read_cr3(vcpu)); mmu_free_roots(vcpu); } static unsigned long get_cr3(struct kvm_vcpu *vcpu) { - return vcpu-arch.cr3; + return kvm_read_cr3(vcpu); } static void inject_page_fault(struct kvm_vcpu *vcpu, @@ -3636,7 +3636,7 @@ static int kvm_pv_mmu_write(struct kvm_vcpu *vcpu, static int kvm_pv_mmu_flush_tlb(struct kvm_vcpu *vcpu) { - (void)kvm_set_cr3(vcpu, vcpu-arch.cr3); + (void)kvm_set_cr3(vcpu, kvm_read_cr3(vcpu)); return 1; } diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index af4b911..a7b04c0 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1174,7 +1174,7 @@ static void svm_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg) switch (reg) { case VCPU_EXREG_PDPTR: BUG_ON(!npt_enabled); - load_pdptrs(vcpu, vcpu-arch.walk_mmu, vcpu-arch.cr3); + load_pdptrs(vcpu, vcpu-arch.walk_mmu, kvm_read_cr3(vcpu)); break; default: BUG(); @@ -2116,7 +2116,7 @@ static int nested_svm_vmexit(struct vcpu_svm *svm) nested_vmcb-save.idtr = vmcb-save.idtr; nested_vmcb-save.efer = svm-vcpu.arch.efer; nested_vmcb-save.cr0= kvm_read_cr0(svm-vcpu); - nested_vmcb-save.cr3= svm-vcpu.arch.cr3; + nested_vmcb-save.cr3= kvm_read_cr3(svm-vcpu); nested_vmcb-save.cr2= vmcb-save.cr2; nested_vmcb-save.cr4= svm-vcpu.arch.cr4; nested_vmcb-save.rflags = vmcb-save.rflags; @@ -2311,7 +2311,7 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) if (npt_enabled) hsave-save.cr3= vmcb-save.cr3; else - hsave-save.cr3= svm-vcpu.arch.cr3; + hsave-save.cr3= kvm_read_cr3(svm-vcpu); copy_vmcb_control_area(hsave, vmcb); @@ -2715,7 +2715,7 @@ static int cr_interception(struct vcpu_svm *svm) val = svm-vcpu.arch.cr2; break; case 3: - val = svm-vcpu.arch.cr3; + val = kvm_read_cr3(svm-vcpu); break; case 4: val = kvm_read_cr4(svm-vcpu); @@ -3693,7 +3693,7 @@ static void set_tdp_cr3(struct kvm_vcpu *vcpu, unsigned long root) mark_dirty(svm-vmcb, VMCB_NPT); /* Also sync guest cr3 here in case we live migrate */ - svm-vmcb-save.cr3 = vcpu-arch.cr3; + svm-vmcb-save.cr3 = kvm_read_cr3(vcpu); mark_dirty(svm-vmcb, VMCB_CR); svm_flush_tlb(vcpu); diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 67c0852..141956e 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1989,7 +1989,7 @@ static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) if (enable_ept) { eptp = construct_eptp(cr3); vmcs_write64(EPT_POINTER, eptp); - guest_cr3 = is_paging(vcpu) ? vcpu-arch.cr3 : + guest_cr3 = is_paging(vcpu) ? kvm_read_cr3(vcpu) : vcpu-kvm-arch.ept_identity_map_addr; ept_load_pdptrs(vcpu); } @@ -3227,8 +3227,9 @@ static int handle_cr(struct kvm_vcpu *vcpu) case 1: /*mov from cr*/ switch (cr) { case 3: - kvm_register_write(vcpu, reg, vcpu-arch.cr3); - trace_kvm_cr_read(cr, vcpu-arch.cr3); + val = kvm_read_cr3(vcpu); + kvm_register_write(vcpu, reg, val); + trace_kvm_cr_read(cr, val); skip_emulated_instruction(vcpu); return 1; case 8: diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 7ad9cda..6e50314 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -473,8 +473,8 @@ static bool pdptrs_changed(struct kvm_vcpu *vcpu) (unsigned long *)vcpu-arch.regs_avail))
[COMMIT master] KVM: MMU: audit: allow audit more guests at the same time
From: Xiao Guangrong xiaoguangr...@cn.fujitsu.com It only allows to audit one guest in the system since: - 'audit_point' is a glob variable - mmu_audit_disable() is called in kvm_mmu_destroy(), so audit is disabled after a guest exited this patch fix those issues then allow to audit more guests at the same time Signed-off-by: Xiao Guangrong xiaoguangr...@cn.fujitsu.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 95f026b..aa75f21 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -461,6 +461,10 @@ struct kvm_arch { /* fields used by HYPER-V emulation */ u64 hv_guest_os_id; u64 hv_hypercall; + + #ifdef CONFIG_KVM_MMU_AUDIT + int audit_point; + #endif }; struct kvm_vm_stat { diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 43bd5e3..afd17f2 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -3533,13 +3533,6 @@ static void mmu_destroy_caches(void) kmem_cache_destroy(mmu_page_header_cache); } -void kvm_mmu_module_exit(void) -{ - mmu_destroy_caches(); - percpu_counter_destroy(kvm_total_used_mmu_pages); - unregister_shrinker(mmu_shrinker); -} - int kvm_mmu_module_init(void) { pte_chain_cache = kmem_cache_create(kvm_pte_chain, @@ -3732,12 +3725,6 @@ int kvm_mmu_get_spte_hierarchy(struct kvm_vcpu *vcpu, u64 addr, u64 sptes[4]) } EXPORT_SYMBOL_GPL(kvm_mmu_get_spte_hierarchy); -#ifdef CONFIG_KVM_MMU_AUDIT -#include mmu_audit.c -#else -static void mmu_audit_disable(void) { } -#endif - void kvm_mmu_destroy(struct kvm_vcpu *vcpu) { ASSERT(vcpu); @@ -3745,5 +3732,18 @@ void kvm_mmu_destroy(struct kvm_vcpu *vcpu) destroy_kvm_mmu(vcpu); free_mmu_pages(vcpu); mmu_free_memory_caches(vcpu); +} + +#ifdef CONFIG_KVM_MMU_AUDIT +#include mmu_audit.c +#else +static void mmu_audit_disable(void) { } +#endif + +void kvm_mmu_module_exit(void) +{ + mmu_destroy_caches(); + percpu_counter_destroy(kvm_total_used_mmu_pages); + unregister_shrinker(mmu_shrinker); mmu_audit_disable(); } diff --git a/arch/x86/kvm/mmu_audit.c b/arch/x86/kvm/mmu_audit.c index ba2bcdd..5f6223b 100644 --- a/arch/x86/kvm/mmu_audit.c +++ b/arch/x86/kvm/mmu_audit.c @@ -19,11 +19,9 @@ #include linux/ratelimit.h -static int audit_point; - -#define audit_printk(fmt, args...) \ +#define audit_printk(kvm, fmt, args...)\ printk(KERN_ERR audit: (%s) error:\ - fmt, audit_point_name[audit_point], ##args) + fmt, audit_point_name[kvm-arch.audit_point], ##args) typedef void (*inspect_spte_fn) (struct kvm_vcpu *vcpu, u64 *sptep, int level); @@ -97,18 +95,21 @@ static void audit_mappings(struct kvm_vcpu *vcpu, u64 *sptep, int level) if (sp-unsync) { if (level != PT_PAGE_TABLE_LEVEL) { - audit_printk(unsync sp: %p level = %d\n, sp, level); + audit_printk(vcpu-kvm, unsync sp: %p +level = %d\n, sp, level); return; } if (*sptep == shadow_notrap_nonpresent_pte) { - audit_printk(notrap spte in unsync sp: %p\n, sp); + audit_printk(vcpu-kvm, notrap spte in unsync +sp: %p\n, sp); return; } } if (sp-role.direct *sptep == shadow_notrap_nonpresent_pte) { - audit_printk(notrap spte in direct sp: %p\n, sp); + audit_printk(vcpu-kvm, notrap spte in direct sp: %p\n, +sp); return; } @@ -125,8 +126,9 @@ static void audit_mappings(struct kvm_vcpu *vcpu, u64 *sptep, int level) hpa = pfn PAGE_SHIFT; if ((*sptep PT64_BASE_ADDR_MASK) != hpa) - audit_printk(levels %d pfn %llx hpa %llx ent %llxn, - vcpu-arch.mmu.root_level, pfn, hpa, *sptep); + audit_printk(vcpu-kvm, levels %d pfn %llx hpa %llx +ent %llxn, vcpu-arch.mmu.root_level, pfn, +hpa, *sptep); } static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep) @@ -142,8 +144,8 @@ static void inspect_spte_has_rmap(struct kvm *kvm, u64 *sptep) if (!gfn_to_memslot(kvm, gfn)) { if (!printk_ratelimit()) return; - audit_printk(no memslot for gfn %llx\n, gfn); - audit_printk(index %ld of sp (gfn=%llx)\n, + audit_printk(kvm, no memslot for gfn %llx\n, gfn); + audit_printk(kvm, index %ld of sp (gfn=%llx)\n, (long int)(sptep - rev_sp-spt), rev_sp-gfn); dump_stack(); return; @@ -153,7 +155,8 @@ static void
[COMMIT master] KVM: VMX: when entering real mode align segment base to 16 bytes
From: Gleb Natapov g...@redhat.com VMX checks that base is equal segment shifted 4 bits left. Otherwise guest entry fails. Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 2260783..f107315 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1736,9 +1736,13 @@ static void fix_rmode_seg(int seg, struct kvm_save_segment *save) save-limit = vmcs_read32(sf-limit); save-ar = vmcs_read32(sf-ar_bytes); vmcs_write16(sf-selector, save-base 4); - vmcs_write32(sf-base, save-base 0xf); + vmcs_write32(sf-base, save-base 0x0); vmcs_write32(sf-limit, 0x); vmcs_write32(sf-ar_bytes, 0xf3); + if (save-base 0xf) + printk_once(KERN_WARNING kvm: segment base is not paragraph +aligned when entering protected mode (seg=%d), + seg); } static void enter_rmode(struct kvm_vcpu *vcpu) -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Add try_main() for running a program under an exception handler
From: Avi Kivity a...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/api/exception.cc b/api/exception.cc index 500569a..910bdff 100644 --- a/api/exception.cc +++ b/api/exception.cc @@ -18,3 +18,16 @@ const char *errno_exception::what() std::strerror(_errno), _errno); return _buf; } + +int try_main(int (*main)(int argc, char** argv), int argc, char** argv, +int ret_on_exception) +{ +try { +return main(argc, argv); +} catch (std::exception e) { +std::fprintf(stderr, exception: %s\n, e.what()); +} catch (...) { +std::fprintf(stderr, unknown exception\n); +} +return ret_on_exception; +} diff --git a/api/exception.hh b/api/exception.hh index 4672760..f78d9a1 100644 --- a/api/exception.hh +++ b/api/exception.hh @@ -13,4 +13,7 @@ private: char _buf[1000]; }; +int try_main(int (*main)(int argc, char** argv), int argc, char** argv, +int ret_on_exception = 127); + #endif -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Add exception class for kernel errors (errno)
From: Avi Kivity a...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/api/exception.cc b/api/exception.cc new file mode 100644 index 000..500569a --- /dev/null +++ b/api/exception.cc @@ -0,0 +1,20 @@ +#include exception.hh +#include cstdio +#include cstring + +errno_exception::errno_exception(int errno) +: _errno(errno) +{ +} + +int errno_exception::errno() const +{ +return _errno; +} + +const char *errno_exception::what() +{ +std::snprintf(_buf, sizeof _buf, error: %s (%d), + std::strerror(_errno), _errno); +return _buf; +} diff --git a/api/exception.hh b/api/exception.hh new file mode 100644 index 000..4672760 --- /dev/null +++ b/api/exception.hh @@ -0,0 +1,16 @@ +#ifndef EXCEPTION_HH +#define EXCEPTION_HH + +#include exception + +class errno_exception : public std::exception { +public: +explicit errno_exception(int err_no); +int errno() const; +virtual const char *what(); +private: +int _errno; +char _buf[1000]; +}; + +#endif -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Introduce a C++ wrapper for the kvm APIs
From: Avi Kivity a...@redhat.com Introduce exception-safe objects for calling system, vm, and vcpu ioctls. Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/api/kvmxx.cc b/api/kvmxx.cc new file mode 100644 index 000..ad27907 --- /dev/null +++ b/api/kvmxx.cc @@ -0,0 +1,185 @@ +#include kvmxx.hh +#include exception.hh +#include fcntl.h +#include sys/ioctl.h +#include sys/mman.h +#include stdlib.h +#include memory +#include algorithm + +namespace kvm { + +static long check_error(long r) +{ +if (r == -1) { + throw errno_exception(errno); +} +return r; +} + +fd::fd(int fd) +: _fd(fd) +{ +} + +fd::fd(const fd other) +: _fd(::dup(other._fd)) +{ +check_error(_fd); +} + +fd::fd(std::string device_node, int flags) +: _fd(::open(device_node.c_str(), flags)) +{ +check_error(_fd); +} + +long fd::ioctl(unsigned nr, long arg) +{ +return check_error(::ioctl(_fd, nr, arg)); +} + +vcpu::vcpu(vm vm, int id) +: _vm(vm), _fd(vm._fd.ioctl(KVM_CREATE_VCPU, id)), _shared(NULL) +, _mmap_size(_vm._system._fd.ioctl(KVM_GET_VCPU_MMAP_SIZE, 0)) + +{ +kvm_run *shared = static_castkvm_run*(::mmap(NULL, _mmap_size, + PROT_READ | PROT_WRITE, + MAP_SHARED, + _fd.get(), 0)); +if (shared == MAP_FAILED) { + throw errno_exception(errno); +} +_shared = shared; +} + +vcpu::~vcpu() +{ +munmap(_shared, _mmap_size); +} + +void vcpu::run() +{ +_fd.ioctl(KVM_RUN, 0); +} + +kvm_regs vcpu::regs() +{ +kvm_regs regs; +_fd.ioctlp(KVM_GET_REGS, regs); +return regs; +} + +void vcpu::set_regs(const kvm_regs regs) +{ +_fd.ioctlp(KVM_SET_REGS, const_castkvm_regs*(regs)); +} + +kvm_sregs vcpu::sregs() +{ +kvm_sregs sregs; +_fd.ioctlp(KVM_GET_SREGS, sregs); +return sregs; +} + +void vcpu::set_sregs(const kvm_sregs sregs) +{ +_fd.ioctlp(KVM_SET_SREGS, const_castkvm_sregs*(sregs)); +} + +class vcpu::kvm_msrs_ptr { +public: +explicit kvm_msrs_ptr(size_t nmsrs); +~kvm_msrs_ptr() { ::free(_kvm_msrs); } +kvm_msrs* operator-() { return _kvm_msrs; } +kvm_msrs* get() { return _kvm_msrs; } +private: +kvm_msrs* _kvm_msrs; +}; + +vcpu::kvm_msrs_ptr::kvm_msrs_ptr(size_t nmsrs) +: _kvm_msrs(0) +{ +size_t size = sizeof(kvm_msrs) + sizeof(kvm_msr_entry) * nmsrs; +_kvm_msrs = static_castkvm_msrs*(::malloc(size)); +if (!_kvm_msrs) { + throw std::bad_alloc(); +} +} + +std::vectorkvm_msr_entry vcpu::msrs(std::vectoruint32_t indices) +{ +kvm_msrs_ptr msrs(indices.size()); +msrs-nmsrs = indices.size(); +for (unsigned i = 0; i msrs-nmsrs; ++i) { + msrs-entries[i].index = indices[i]; +} +_fd.ioctlp(KVM_GET_MSRS, msrs.get()); +return std::vectorkvm_msr_entry(msrs-entries, + msrs-entries + msrs-nmsrs); +} + +void vcpu::set_msrs(const std::vectorkvm_msr_entry msrs) +{ +kvm_msrs_ptr _msrs(msrs.size()); +_msrs-nmsrs = msrs.size(); +std::copy(msrs.begin(), msrs.end(), _msrs-entries); +_fd.ioctlp(KVM_SET_MSRS, _msrs.get()); +} + +void vcpu::set_debug(uint64_t dr[8], bool enabled, bool singlestep) +{ +kvm_guest_debug gd; + +gd.control = 0; +if (enabled) { + gd.control |= KVM_GUESTDBG_ENABLE; +} +if (singlestep) { + gd.control |= KVM_GUESTDBG_SINGLESTEP; +} +for (int i = 0; i 8; ++i) { + gd.arch.debugreg[i] = dr[i]; +} +_fd.ioctlp(KVM_SET_GUEST_DEBUG, gd); +} + +vm::vm(system system) +: _system(system), _fd(system._fd.ioctl(KVM_CREATE_VM, 0)) +{ +} + +void vm::set_memory_region(int slot, void *addr, uint64_t gpa, size_t len) +{ +struct kvm_userspace_memory_region umr; + +umr.slot = slot; +umr.flags = 0; +umr.guest_phys_addr = gpa; +umr.memory_size = len; +umr.userspace_addr = reinterpret_castuint64_t(addr); +_fd.ioctlp(KVM_SET_USER_MEMORY_REGION, umr); +} + +void vm::set_tss_addr(uint32_t addr) +{ +_fd.ioctl(KVM_SET_TSS_ADDR, addr); +} + +system::system(std::string device_node) +: _fd(device_node, O_RDWR) +{ +} + +bool system::check_extension(int extension) +{ +return _fd.ioctl(KVM_CHECK_EXTENSION, extension); +} + +int system::get_extension_int(int extension) +{ +return _fd.ioctl(KVM_CHECK_EXTENSION, extension); +} + +}; diff --git a/api/kvmxx.hh b/api/kvmxx.hh new file mode 100644 index 000..51dbe7a --- /dev/null +++ b/api/kvmxx.hh @@ -0,0 +1,83 @@ +#ifndef KVMXX_H +#define KVMXX_H + +#include string +#include signal.h +#include unistd.h +#include vector +#include errno.h +#include linux/kvm.h +#include stdint.h + +namespace kvm { + +class system; +class vm; +class vcpu; +class fd; + +class fd { +public: +explicit fd(int n); +explicit fd(std::string path, int flags); +fd(const fd other); +~fd() { ::close(_fd); } +int get() {
[COMMIT master] Makefile: add support for C++
From: Avi Kivity a...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/Makefile b/Makefile index d25e6f2..9b0256d 100644 --- a/Makefile +++ b/Makefile @@ -30,11 +30,13 @@ CFLAGS += -O1 CFLAGS += $(autodepend-flags) -g -fomit-frame-pointer -Wall CFLAGS += $(call cc-option, -fno-stack-protector, ) CFLAGS += $(call cc-option, -fno-stack-protector-all, ) +CFLAGS += -I. -CXXFLAGS = $(autodepend-flags) +CXXFLAGS += $(CFLAGS) autodepend-flags = -MMD -MF $(dir $*).$(notdir $*).d +LDFLAGS += $(CFLAGS) LDFLAGS += -pthread -lrt kvmtrace_objs= kvmtrace.o -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Improve autodepend includes
From: Avi Kivity a...@redhat.com Instead of listing all directories explicitly, include all autodepend files. Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/Makefile b/Makefile index 9b0256d..85ebd37 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ $(libcflat): $(cflatobjs) %.o: %.S $(CC) $(CFLAGS) -c -nostdlib -o $@ $ --include .*.d +-include .*.d */.*.d */*/.*.d install: mkdir -p $(DESTDIR) diff --git a/config-x86-common.mak b/config-x86-common.mak index c5508b3..d22df17 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -81,4 +81,3 @@ arch_clean: $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \ $(TEST_DIR)/.*.d $(TEST_DIR)/lib/.*.d $(TEST_DIR)/lib/*.o --include $(TEST_DIR)/.*.d lib/.*.d lib/x86/.*.d -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] api: add memory map management
From: Avi Kivity a...@redhat.com Add a class to manage the memory map and a class to represent a memory slot. Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/api/memmap.cc b/api/memmap.cc new file mode 100644 index 000..c625852 --- /dev/null +++ b/api/memmap.cc @@ -0,0 +1,76 @@ + +#include memmap.hh + +mem_slot::mem_slot(mem_map map, uint64_t gpa, uint64_t size, void* hva) +: _map(map) +, _slot(map._free_slots.top()) +, _gpa(gpa) +, _size(size) +, _hva(hva) +, _dirty_log_enabled(false) +, _log() +{ +map._free_slots.pop(); +update(); +} + +mem_slot::~mem_slot() +{ +_size = 0; +try { +update(); +_map._free_slots.push(_slot); +} catch (...) { +// can't do much if we can't undo slot registration - leak the slot +} +} + +void mem_slot::set_dirty_logging(bool enabled) +{ +if (_dirty_log_enabled != enabled) { +_dirty_log_enabled = enabled; +if (enabled) { +int logsize = ((_size 12) + bits_per_word - 1) / bits_per_word; +_log.resize(logsize); +} else { +_log.resize(0); +} +update(); +} +} + +void mem_slot::update() +{ +uint32_t flags = 0; +if (_dirty_log_enabled) { +flags |= KVM_MEM_LOG_DIRTY_PAGES; +} +_map._vm.set_memory_region(_slot, _hva, _gpa, _size, flags); +} + +bool mem_slot::dirty_logging() const +{ +return _dirty_log_enabled; +} + +void mem_slot::update_dirty_log() +{ +_map._vm.get_dirty_log(_slot, _log[0]); +} + +bool mem_slot::is_dirty(uint64_t gpa) const +{ +uint64_t pagenr = (gpa - _gpa) 12; +ulong wordnr = pagenr / bits_per_word; +ulong bit = 1ULL (pagenr % bits_per_word); +return _log[wordnr] bit; +} + +mem_map::mem_map(kvm::vm vm) +: _vm(vm) +{ +int nr_slots = vm.sys().get_extension_int(KVM_CAP_NR_MEMSLOTS); +for (int i = 0; i nr_slots; ++i) { +_free_slots.push(i); +} +} diff --git a/api/memmap.hh b/api/memmap.hh new file mode 100644 index 000..59ec619 --- /dev/null +++ b/api/memmap.hh @@ -0,0 +1,43 @@ +#ifndef MEMMAP_HH +#define MEMMAP_HH + +#include kvmxx.hh +#include stdint.h +#include vector +#include stack + +class mem_map; +class mem_slot; + +class mem_slot { +public: +mem_slot(mem_map map, uint64_t gpa, uint64_t size, void *hva); +~mem_slot(); +void set_dirty_logging(bool enabled); +bool dirty_logging() const; +void update_dirty_log(); +bool is_dirty(uint64_t gpa) const; +private: +void update(); +private: +typedef unsigned long ulong; +static const int bits_per_word = sizeof(ulong) * 8; +mem_map _map; +int _slot; +uint64_t _gpa; +uint64_t _size; +void *_hva; +bool _dirty_log_enabled; +std::vectorulong _log; +}; + +class mem_map { +public: +mem_map(kvm::vm vm); +private: +kvm::vm _vm; +std::stackint _free_slots; +friend class mem_slot; +}; + +#endif -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] api: add support for KVM_SET_USER_MEMORY_REGION flags field
From: Avi Kivity a...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/api/kvmxx.cc b/api/kvmxx.cc index ad27907..42e8781 100644 --- a/api/kvmxx.cc +++ b/api/kvmxx.cc @@ -150,12 +150,13 @@ vm::vm(system system) { } -void vm::set_memory_region(int slot, void *addr, uint64_t gpa, size_t len) +void vm::set_memory_region(int slot, void *addr, uint64_t gpa, size_t len, + uint32_t flags) { struct kvm_userspace_memory_region umr; umr.slot = slot; -umr.flags = 0; +umr.flags = flags; umr.guest_phys_addr = gpa; umr.memory_size = len; umr.userspace_addr = reinterpret_castuint64_t(addr); diff --git a/api/kvmxx.hh b/api/kvmxx.hh index 51dbe7a..958d36f 100644 --- a/api/kvmxx.hh +++ b/api/kvmxx.hh @@ -57,7 +57,8 @@ private: class vm { public: explicit vm(system system); -void set_memory_region(int slot, void *addr, uint64_t gpa, size_t len); +void set_memory_region(int slot, void *addr, uint64_t gpa, size_t len, + uint32_t flags = 0); void set_tss_addr(uint32_t addr); system sys() { return _system; } private: -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Add sample test using the api test harness
From: Avi Kivity a...@redhat.com Call a function setting a global variable. Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/api/api-sample.cc b/api/api-sample.cc new file mode 100644 index 000..8d57c09 --- /dev/null +++ b/api/api-sample.cc @@ -0,0 +1,29 @@ + +#include api/kvmxx.hh +#include api/identity.hh +#include api/exception.hh +#include stdio.h + +static int global = 0; + +static void set_global() +{ +global = 1; +} + +int test_main(int ac, char** av) +{ +kvm::system system; +kvm::vm vm(system); +identity::setup_vm(vm); +kvm::vcpu vcpu(vm, 0); +identity::vcpu thread(vcpu, set_global); +vcpu.run(); +printf(global %d\n, global); +return global == 1 ? 0 : 1; +} + +int main(int ac, char** av) +{ +return try_main(test_main, ac, av); +} diff --git a/config-x86-common.mak b/config-x86-common.mak index dde4f67..3e8e641 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -32,6 +32,8 @@ tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \ $(TEST_DIR)/hypercall.flat $(TEST_DIR)/sieve.flat \ $(TEST_DIR)/kvmclock_test.flat +tests-common += api/api-sample + tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg test_cases: $(tests-common) $(tests) @@ -82,3 +84,8 @@ arch_clean: $(TEST_DIR)/.*.d $(TEST_DIR)/lib/.*.d $(TEST_DIR)/lib/*.o api/%.o: CFLAGS += -m32 + +api/api-sample: LDLIBS += -lstdc++ +api/api-sample: LDFLAGS += -m32 + +api/api-sample: api/api-sample.o api/kvmxx.o api/identity.o api/exception.o -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] api: support KVM_GET_DIRTY_LOG ioctl
From: Avi Kivity a...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/api/kvmxx.cc b/api/kvmxx.cc index 42e8781..7ebebb5 100644 --- a/api/kvmxx.cc +++ b/api/kvmxx.cc @@ -163,6 +163,14 @@ void vm::set_memory_region(int slot, void *addr, uint64_t gpa, size_t len, _fd.ioctlp(KVM_SET_USER_MEMORY_REGION, umr); } +void vm::get_dirty_log(int slot, void *log) +{ +struct kvm_dirty_log kdl; +kdl.slot = slot; +kdl.dirty_bitmap = log; +_fd.ioctlp(KVM_GET_DIRTY_LOG, kdl); +} + void vm::set_tss_addr(uint32_t addr) { _fd.ioctl(KVM_SET_TSS_ADDR, addr); diff --git a/api/kvmxx.hh b/api/kvmxx.hh index 958d36f..1dcb41d 100644 --- a/api/kvmxx.hh +++ b/api/kvmxx.hh @@ -59,6 +59,7 @@ public: explicit vm(system system); void set_memory_region(int slot, void *addr, uint64_t gpa, size_t len, uint32_t flags = 0); +void get_dirty_log(int slot, void *log); void set_tss_addr(uint32_t addr); system sys() { return _system; } private: -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Build tests with debug information
From: Avi Kivity a...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/Makefile b/Makefile index 85ebd37..b6e8759 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ DESTDIR := $(PREFIX)/share/qemu/tests .PHONY: arch_clean clean #make sure env CFLAGS variable is not used -CFLAGS = +CFLAGS = -g libgcc := $(shell $(CC) --print-libgcc-file-name) -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Add support for calling a function in guest mode
From: Avi Kivity a...@redhat.com This patch provides a way to establish an identity guest which has a 1:1 gva-hva translation. This allows the host to switch to guest mode, call a function in the same address space, and return. Because long mode virtual addresses are 47 bits long, and some hosts have smaller physical addresses, we target 32-bit mode only. On x86_64 the code needs to be run with 'setarch i386 -3' to limit the address space to 3GB, so the address space occupied by the local APIC is left unused. Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/api/identity.cc b/api/identity.cc new file mode 100644 index 000..de52f68 --- /dev/null +++ b/api/identity.cc @@ -0,0 +1,76 @@ + +#include identity.hh +#include stdio.h + +namespace identity { + +typedef unsigned long ulong; + +void setup_vm(kvm::vm vm) +{ +vm.set_memory_region(0, NULL, 0, 3UL 30); +vm.set_tss_addr(3UL 30); +} + +void vcpu::setup_sregs() +{ +kvm_sregs sregs = { }; +kvm_segment dseg = { }; +dseg.base = 0; dseg.limit = -1U; dseg.type = 3; dseg.present = 1; +dseg.dpl = 3; dseg.db = 1; dseg.s = 1; dseg.l = 0; dseg.g = 1; +kvm_segment cseg = dseg; +cseg.type = 11; + +sregs.cs = cseg; asm (mov %%cs, %0 : =rm(sregs.cs.selector)); +sregs.ds = dseg; asm (mov %%ds, %0 : =rm(sregs.ds.selector)); +sregs.es = dseg; asm (mov %%es, %0 : =rm(sregs.es.selector)); +sregs.fs = dseg; asm (mov %%fs, %0 : =rm(sregs.fs.selector)); +sregs.gs = dseg; asm (mov %%gs, %0 : =rm(sregs.gs.selector)); +sregs.ss = dseg; asm (mov %%ss, %0 : =rm(sregs.ss.selector)); + +uint32_t gsbase; +asm (mov %%gs:0, %0 : =r(gsbase)); +sregs.gs.base = gsbase; + +sregs.tr.base = reinterpret_castulong(*_stack.begin()); +sregs.tr.type = 11; +sregs.tr.s = 0; +sregs.tr.present = 1; + +sregs.cr0 = 0x11; /* PE, ET, !PG */ +sregs.cr4 = 0; +sregs.efer = 0; +sregs.apic_base = 0xfee0; +_vcpu.set_sregs(sregs); +} + +void vcpu::thunk(vcpu* zis) +{ +zis-_guest_func(); +asm volatile(outb %%al, %%dx : : a(0), d(0)); +} + +void vcpu::setup_regs() +{ +kvm_regs regs = {}; +regs.rflags = 0x3202; +regs.rsp = reinterpret_castulong(*_stack.end()); +regs.rsp = ~15UL; +ulong* sp = reinterpret_castulong *(regs.rsp); +*--sp = reinterpret_castulong((char*)this); +*--sp = 0; +regs.rsp = reinterpret_castulong(sp); +regs.rip = reinterpret_castulong(vcpu::thunk); +printf(rip %llx\n, regs.rip); +_vcpu.set_regs(regs); +} + +vcpu::vcpu(kvm::vcpu vcpu, std::tr1::functionvoid () guest_func, + unsigned long stack_size) +: _vcpu(vcpu), _guest_func(guest_func), _stack(stack_size) +{ +setup_sregs(); +setup_regs(); +} + +} diff --git a/api/identity.hh b/api/identity.hh new file mode 100644 index 000..7401826 --- /dev/null +++ b/api/identity.hh @@ -0,0 +1,28 @@ +#ifndef API_IDENTITY_HH +#define API_IDENTITY_HH + +#include kvmxx.hh +#include tr1/functional +#include vector + +namespace identity { + +void setup_vm(kvm::vm vm); + +class vcpu { +public: +vcpu(kvm::vcpu vcpu, std::tr1::functionvoid () guest_func, +unsigned long stack_size = 256 * 1024); +private: +static void thunk(vcpu* vcpu); +void setup_regs(); +void setup_sregs(); +private: +kvm::vcpu _vcpu; +std::tr1::functionvoid () _guest_func; +std::vectorchar _stack; +}; + +} + +#endif diff --git a/config-x86-common.mak b/config-x86-common.mak index d22df17..dde4f67 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -81,3 +81,4 @@ arch_clean: $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \ $(TEST_DIR)/.*.d $(TEST_DIR)/lib/.*.d $(TEST_DIR)/lib/*.o +api/%.o: CFLAGS += -m32 -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Add dirty log test
From: Avi Kivity a...@redhat.com This checks the failure that was fixed by kernel commit edde99ce0529 (KVM: Write protect memory after slot swap). Two threads are used; a guest thread continuously updates a shared variable, which is also sampled by a host thread that also checks if dirty logging marked it as dirty. It detects about 5 million failures with the fix reverted, and 0 failures with the fix applied. Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/api/dirty-log.cc b/api/dirty-log.cc new file mode 100644 index 000..1e4ef9e --- /dev/null +++ b/api/dirty-log.cc @@ -0,0 +1,78 @@ +#include kvmxx.hh +#include memmap.hh +#include identity.hh +#include boost/thread/thread.hpp +#include stdlib.h +#include stdio.h + +namespace { + +void delay_loop(unsigned n) +{ +for (unsigned i = 0; i n; ++i) { +asm volatile(pause); +} + } + +void write_mem(volatile bool running, volatile int* shared_var) +{ +while (running) { +++*shared_var; +delay_loop(1000); +} +} + +void check_dirty_log(mem_slot slot, + volatile bool running, + volatile int* shared_var, + int nr_fail) +{ +uint64_t shared_var_gpa = reinterpret_castuint64_t(shared_var); +slot.set_dirty_logging(true); +slot.update_dirty_log(); +for (int i = 0; i 1000; ++i) { +int sample1 = *shared_var; +delay_loop(600); +int sample2 = *shared_var; +slot.update_dirty_log(); +if (!slot.is_dirty(shared_var_gpa) sample1 != sample2) { +++nr_fail; +} +} +running = false; +slot.set_dirty_logging(false); +} + +} + +using boost::ref; +using std::tr1::bind; + +int main(int ac, char **av) +{ +kvm::system sys; +kvm::vm vm(sys); +mem_map memmap(vm); +void* logged_slot_virt; +posix_memalign(logged_slot_virt, 4096, 4096); +int* shared_var = static_castint*(logged_slot_virt); +identity::hole hole(logged_slot_virt, 4096); +identity::vm ident_vm(vm, memmap, hole); +kvm::vcpu vcpu(vm, 0); +bool running = true; +int nr_fail = 0; +mem_slot logged_slot(memmap, + reinterpret_castuint64_t(logged_slot_virt), + 4096, logged_slot_virt); +boost::thread host_poll_thread(check_dirty_log, ref(logged_slot), + ref(running), + ref(shared_var), ref(nr_fail)); +identity::vcpu guest_write_thread(vcpu, + bind(write_mem, + ref(running), + ref(shared_var))); +vcpu.run(); +host_poll_thread.join(); +printf(Dirty bitmap failures: %d\n, nr_fail); +return nr_fail == 0 ? 0 : 1; +} diff --git a/config-x86-common.mak b/config-x86-common.mak index ce36cde..b5c49f4 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -33,6 +33,7 @@ tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \ $(TEST_DIR)/kvmclock_test.flat tests-common += api/api-sample +tests-common += api/dirty-log tests_and_config = $(TEST_DIR)/*.flat $(TEST_DIR)/unittests.cfg @@ -85,10 +86,12 @@ arch_clean: api/%.o: CFLAGS += -m32 -api/%: LDLIBS += -lstdc++ +api/%: LDLIBS += -lstdc++ -lboost_thread-mt -lpthread api/%: LDFLAGS += -m32 api/libapi.a: api/kvmxx.o api/identity.o api/exception.o api/memmap.o $(AR) rcs $@ $^ -api/api-sample: api/api-sample.o api/libapi.a \ No newline at end of file +api/api-sample: api/api-sample.o api/libapi.a + +api/dirty-log: api/dirty-log.o api/libapi.a -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Introduce libapi.a to avoid long Makefile recipes
From: Avi Kivity a...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/config-x86-common.mak b/config-x86-common.mak index 436f4bd..ce36cde 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -85,8 +85,10 @@ arch_clean: api/%.o: CFLAGS += -m32 -api/api-sample: LDLIBS += -lstdc++ -api/api-sample: LDFLAGS += -m32 +api/%: LDLIBS += -lstdc++ +api/%: LDFLAGS += -m32 -api/api-sample: api/api-sample.o api/kvmxx.o api/identity.o api/exception.o -api/api-sample: api/memmap.o \ No newline at end of file +api/libapi.a: api/kvmxx.o api/identity.o api/exception.o api/memmap.o + $(AR) rcs $@ $^ + +api/api-sample: api/api-sample.o api/libapi.a \ No newline at end of file -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Honor cpuid.nx when enabling efer.nxe
From: Avi Kivity a...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/x86/vmexit.c b/x86/vmexit.c index 551083d..67746c6 100644 --- a/x86/vmexit.c +++ b/x86/vmexit.c @@ -144,7 +144,8 @@ static void do_test(struct test *test) static void enable_nx(void *junk) { - wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NX_MASK); + if (cpuid(0x8001).d (1 20)) + wrmsr(MSR_EFER, rdmsr(MSR_EFER) | EFER_NX_MASK); } int main(void) -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] api: Add support for creating an identity map with a hole
From: Avi Kivity a...@redhat.com The hole may be used for mmio or dirty logging. Signed-off-by: Avi Kivity a...@redhat.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com diff --git a/api/api-sample.cc b/api/api-sample.cc index 8d57c09..524ad7b 100644 --- a/api/api-sample.cc +++ b/api/api-sample.cc @@ -15,7 +15,8 @@ int test_main(int ac, char** av) { kvm::system system; kvm::vm vm(system); -identity::setup_vm(vm); +mem_map memmap(vm); +identity::vm ident_vm(vm, memmap); kvm::vcpu vcpu(vm, 0); identity::vcpu thread(vcpu, set_global); vcpu.run(); diff --git a/api/identity.cc b/api/identity.cc index de52f68..e04231b 100644 --- a/api/identity.cc +++ b/api/identity.cc @@ -6,9 +6,28 @@ namespace identity { typedef unsigned long ulong; -void setup_vm(kvm::vm vm) +hole::hole() +: address(), size() { -vm.set_memory_region(0, NULL, 0, 3UL 30); +} + +hole::hole(void* address, size_t size) +: address(address), size(size) +{ +} + +vm::vm(kvm::vm vm, mem_map mmap, hole h) +{ +uint64_t hole_gpa = reinterpret_castuint64_t(h.address); +char* hole_hva = static_castchar*(h.address); +if (h.address) { +_slots.push_back(mem_slot_ptr(new mem_slot(mmap, 0, hole_gpa, NULL))); +} +uint64_t hole_end = hole_gpa + h.size; +uint64_t end = 3U 30; +_slots.push_back(mem_slot_ptr(new mem_slot(mmap, hole_end, + end - hole_end, + hole_hva + h.size))); vm.set_tss_addr(3UL 30); } diff --git a/api/identity.hh b/api/identity.hh index 7401826..4491043 100644 --- a/api/identity.hh +++ b/api/identity.hh @@ -2,12 +2,27 @@ #define API_IDENTITY_HH #include kvmxx.hh +#include memmap.hh #include tr1/functional +#include tr1/memory #include vector namespace identity { -void setup_vm(kvm::vm vm); +struct hole { +hole(); +hole(void* address, size_t size); +void* address; +size_t size; +}; + +class vm { +public: +vm(kvm::vm vm, mem_map mmap, hole address_space_hole = hole()); +private: +typedef std::tr1::shared_ptrmem_slot mem_slot_ptr; +std::vectormem_slot_ptr _slots; +}; class vcpu { public: diff --git a/config-x86-common.mak b/config-x86-common.mak index 3e8e641..436f4bd 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -89,3 +89,4 @@ api/api-sample: LDLIBS += -lstdc++ api/api-sample: LDFLAGS += -m32 api/api-sample: api/api-sample.o api/kvmxx.o api/identity.o api/exception.o +api/api-sample: api/memmap.o \ No newline at end of file -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] access test: dump page mapping if test fail
From: Xiao Guangrong xiaoguangr...@cn.fujitsu.com It can help us to fix the bug Signed-off-by: Xiao Guangrong xiaoguangr...@cn.fujitsu.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/x86/access.c b/x86/access.c index f43f7f1..709d1a6 100644 --- a/x86/access.c +++ b/x86/access.c @@ -35,6 +35,9 @@ typedef unsigned long pt_element_t; #define MSR_EFER 0xc080 #define EFER_NX_MASK (1ull 11) +#define PT_INDEX(address, level) \ + ((address) (12 + ((level)-1) * 9)) 511 + /* * page table access check tests */ @@ -420,7 +423,7 @@ void __ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, u64 pd_page, at-ptep = 0; for (int i = 4; i = 1 (i = 2 || !at-flags[AC_PDE_PSE]); --i) { pt_element_t *vroot = va(root PT_BASE_ADDR_MASK); - unsigned index = ((unsigned long)at-virt (12 + (i-1) * 9)) 511; + unsigned index = PT_INDEX((unsigned long)at-virt, i); pt_element_t pte = 0; switch (i) { case 4: @@ -487,6 +490,22 @@ static void ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, return __ac_setup_specific_pages(at, pool, pd_page, pt_page); } +static void dump_mapping(ac_test_t *at) +{ + unsigned long root = read_cr3(); + int i; + + printf(Dump mapping: address: %llx\n, at-virt); + for (i = 4; i = 1 (i = 2 || !at-flags[AC_PDE_PSE]); --i) { + pt_element_t *vroot = va(root PT_BASE_ADDR_MASK); + unsigned index = PT_INDEX((unsigned long)at-virt, i); + pt_element_t pte = vroot[index]; + + printf(--L%d: %llx\n, i, pte); + root = vroot[index]; + } +} + static void ac_test_check(ac_test_t *at, _Bool *success_ret, _Bool cond, const char *fmt, ...) { @@ -511,6 +530,7 @@ static void ac_test_check(ac_test_t *at, _Bool *success_ret, _Bool cond, vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); printf(FAIL: %s\n, buf); +dump_mapping(at); } static int pt_match(pt_element_t pte1, pt_element_t pte2, pt_element_t ignore) -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] access test: add the test case to check PFEC on prefetch pte path
From: Xiao Guangrong xiaoguangr...@cn.fujitsu.com Check page fault error code on prefetch pte path Signed-off-by: Xiao Guangrong xiaoguangr...@cn.fujitsu.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/x86/access.c b/x86/access.c index 067565b..f43f7f1 100644 --- a/x86/access.c +++ b/x86/access.c @@ -408,7 +408,9 @@ fault: at-expected_error = ~PFERR_FETCH_MASK; } -void ac_test_setup_pte(ac_test_t *at, ac_pool_t *pool) +void __ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, u64 pd_page, + u64 pt_page) + { unsigned long root = read_cr3(); @@ -423,13 +425,12 @@ void ac_test_setup_pte(ac_test_t *at, ac_pool_t *pool) switch (i) { case 4: case 3: - pte = vroot[index]; - pte = ac_test_alloc_pt(pool) | PT_PRESENT_MASK; - pte |= PT_WRITABLE_MASK | PT_USER_MASK; + pte = pd_page ? pd_page : ac_test_alloc_pt(pool); + pte |= PT_PRESENT_MASK | PT_WRITABLE_MASK | PT_USER_MASK; break; case 2: if (!at-flags[AC_PDE_PSE]) - pte = ac_test_alloc_pt(pool); + pte = pt_page ? pt_page : ac_test_alloc_pt(pool); else { pte = at-phys PT_PSE_BASE_ADDR_MASK; pte |= PT_PSE_MASK; @@ -475,6 +476,17 @@ void ac_test_setup_pte(ac_test_t *at, ac_pool_t *pool) ac_set_expected_status(at); } +static void ac_test_setup_pte(ac_test_t *at, ac_pool_t *pool) +{ + __ac_setup_specific_pages(at, pool, 0, 0); +} + +static void ac_setup_specific_pages(ac_test_t *at, ac_pool_t *pool, + u64 pd_page, u64 pt_page) +{ + return __ac_setup_specific_pages(at, pool, pd_page, pt_page); +} + static void ac_test_check(ac_test_t *at, _Bool *success_ret, _Bool cond, const char *fmt, ...) { @@ -663,6 +675,43 @@ err: return 0; } +/* + * This test case is used to triger the bug which is fixed by + * commit 3ddf6c06e13e in the kvm tree + */ +static int check_pfec_on_prefetch_pte(ac_pool_t *pool) +{ + ac_test_t at1, at2; + + ac_test_init(at1, (void *)(0x123406001000)); + ac_test_init(at2, (void *)(0x123406003000)); + + at1.flags[AC_PDE_PRESENT] = 1; + at1.flags[AC_PTE_PRESENT] = 1; + ac_setup_specific_pages(at1, pool, 30 * 1024 * 1024, 30 * 1024 * 1024); + + at2.flags[AC_PDE_PRESENT] = 1; + at2.flags[AC_PTE_NX] = 1; + at2.flags[AC_PTE_PRESENT] = 1; + ac_setup_specific_pages(at2, pool, 30 * 1024 * 1024, 30 * 1024 * 1024); + + if (!ac_test_do_access(at1)) { + printf(%s: prepare fail\n, __FUNCTION__); + goto err; + } + + if (!ac_test_do_access(at2)) { + printf(%s: check PFEC on prefetch pte path fail\n, + __FUNCTION__); + goto err; + } + + return 1; + +err: +return 0; +} + int ac_test_exec(ac_test_t *at, ac_pool_t *pool) { int r; @@ -675,11 +724,18 @@ int ac_test_exec(ac_test_t *at, ac_pool_t *pool) return r; } +typedef int (*ac_test_fn)(ac_pool_t *pool); +const ac_test_fn ac_test_cases[] = +{ + corrupt_hugepage_triger, + check_pfec_on_prefetch_pte, +}; + int ac_test_run(void) { ac_test_t at; ac_pool_t pool; -int tests, successes; +int i, tests, successes; printf(run\n); tests = successes = 0; @@ -690,8 +746,10 @@ int ac_test_run(void) successes += ac_test_exec(at, pool); } while (ac_test_bump(at)); -++tests; -successes += corrupt_hugepage_triger(pool); +for (i = 0; i ARRAY_SIZE(ac_test_cases); i++) { + ++tests; + successes += ac_test_cases[i](pool); +} printf(\n%d tests, %d failures\n, tests, tests - successes); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Make access.c use library functions
From: Gleb Natapov g...@redhat.com access.c has functions that are provided by library code. Remove them and use library functions instead. Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/x86/access.c b/x86/access.c index 709d1a6..1c638a7 100644 --- a/x86/access.c +++ b/x86/access.c @@ -1,5 +1,7 @@ #include libcflat.h +#include idt.h +#include processor.h #define smp_id() 0 @@ -101,34 +103,6 @@ static inline void *va(pt_element_t phys) return (void *)phys; } -static unsigned long read_cr0() -{ -unsigned long cr0; - -asm volatile (mov %%cr0, %0 : =r(cr0)); - -return cr0; -} - -static void write_cr0(unsigned long cr0) -{ -asm volatile (mov %0, %%cr0 : : r(cr0)); -} - -typedef struct { -unsigned short offset0; -unsigned short selector; -unsigned short ist : 3; -unsigned short : 5; -unsigned short type : 4; -unsigned short : 1; -unsigned short dpl : 2; -unsigned short p : 1; -unsigned short offset1; -unsigned offset2; -unsigned reserved; -} idt_entry_t; - typedef struct { pt_element_t pt_pool; unsigned pt_pool_size; @@ -146,7 +120,6 @@ typedef struct { pt_element_t ignore_pde; int expected_fault; unsigned expected_error; -idt_entry_t idt[256]; } ac_test_t; typedef struct { @@ -157,51 +130,6 @@ typedef struct { static void ac_test_show(ac_test_t *at); -void lidt(idt_entry_t *idt, int nentries) -{ -descriptor_table_t dt; - -dt.limit = nentries * sizeof(*idt) - 1; -dt.linear_addr = (unsigned long)idt; -asm volatile (lidt %0 : : m(dt)); -} - -unsigned short read_cs() -{ -unsigned short r; - -asm volatile (mov %%cs, %0 : =r(r)); -return r; -} - -unsigned long long rdmsr(unsigned index) -{ -unsigned a, d; - -asm volatile(rdmsr : =a(a), =d(d) : c(index)); -return ((unsigned long long)d 32) | a; -} - -void wrmsr(unsigned index, unsigned long long val) -{ -unsigned a = val, d = val 32; - -asm volatile(wrmsr : : a(a), d(d), c(index)); -} - -void set_idt_entry(idt_entry_t *e, void *addr, int dpl) -{ -memset(e, 0, sizeof *e); -e-offset0 = (unsigned long)addr; -e-selector = read_cs(); -e-ist = 0; -e-type = 14; -e-dpl = dpl; -e-p = 1; -e-offset1 = (unsigned long)addr 16; -e-offset2 = (unsigned long)addr 32; -} - void set_cr0_wp(int wp) { unsigned long cr0 = read_cr0(); @@ -225,13 +153,11 @@ void set_efer_nx(int nx) static void ac_env_int(ac_pool_t *pool) { -static idt_entry_t idt[256]; +setup_idt(); -memset(idt, 0, sizeof(idt)); -lidt(idt, 256); extern char page_fault, kernel_entry; -set_idt_entry(idt[14], page_fault, 0); -set_idt_entry(idt[0x20], kernel_entry, 3); +set_idt_entry(14, page_fault, 0); +set_idt_entry(0x20, kernel_entry, 3); pool-pt_pool = 33 * 1024 * 1024; pool-pt_pool_size = 120 * 1024 * 1024 - pool-pt_pool; @@ -276,14 +202,6 @@ int ac_test_bump(ac_test_t *at) return ret; } -unsigned long read_cr3() -{ -unsigned long cr3; - -asm volatile (mov %%cr3, %0 : =r(cr3)); -return cr3; -} - void invlpg(void *addr) { asm volatile (invlpg (%0) : : r(addr)); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Remove duplicated idt code from apic test
From: Gleb Natapov g...@redhat.com Use library idt code instead. Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/x86/apic.c b/x86/apic.c index 2207040..6d06f9f 100644 --- a/x86/apic.c +++ b/x86/apic.c @@ -2,22 +2,7 @@ #include apic.h #include vm.h #include smp.h - -typedef struct { -unsigned short offset0; -unsigned short selector; -unsigned short ist : 3; -unsigned short : 5; -unsigned short type : 4; -unsigned short : 1; -unsigned short dpl : 2; -unsigned short p : 1; -unsigned short offset1; -#ifdef __x86_64__ -unsigned offset2; -unsigned reserved; -#endif -} idt_entry_t; +#include idt.h typedef struct { ulong regs[sizeof(ulong)*2]; @@ -90,8 +75,6 @@ asm ( #endif ); -static idt_entry_t *idt = 0; - static int g_fail; static int g_tests; @@ -128,22 +111,12 @@ void test_enable_x2apic(void) } } -static void set_idt_entry(unsigned vec, void (*func)(isr_regs_t *regs)) +static void handle_irq(unsigned vec, void (*func)(isr_regs_t *regs)) { u8 *thunk = vmalloc(50); -ulong ptr = (ulong)thunk; -idt_entry_t ent = { -.offset0 = ptr, -.selector = read_cs(), -.ist = 0, -.type = 14, -.dpl = 0, -.p = 1, -.offset1 = ptr 16, -#ifdef __x86_64__ -.offset2 = ptr 32, -#endif -}; + +set_idt_entry(vec, thunk, 0); + #ifdef __x86_64__ /* sub $8, %rsp */ *thunk++ = 0x48; *thunk++ = 0x83; *thunk++ = 0xec; *thunk++ = 0x08; @@ -164,7 +137,6 @@ static void set_idt_entry(unsigned vec, void (*func)(isr_regs_t *regs)) *thunk ++ = 0xe9; *(u32 *)thunk = (ulong)isr_entry_point - (ulong)(thunk + 4); #endif -idt[vec] = ent; } static void irq_disable(void) @@ -194,7 +166,7 @@ static void test_self_ipi(void) { int vec = 0xf1; -set_idt_entry(vec, self_ipi_isr); +handle_irq(vec, self_ipi_isr); irq_enable(); apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED | vec, 0); @@ -234,7 +206,7 @@ static void ioapic_isr_77(isr_regs_t *regs) static void test_ioapic_intr(void) { -set_idt_entry(0x77, ioapic_isr_77); +handle_irq(0x77, ioapic_isr_77); set_ioapic_redir(0x10, 0x77); toggle_irq_line(0x10); asm volatile (nop); @@ -262,8 +234,8 @@ static void ioapic_isr_66(isr_regs_t *regs) static void test_ioapic_simultaneous(void) { -set_idt_entry(0x78, ioapic_isr_78); -set_idt_entry(0x66, ioapic_isr_66); +handle_irq(0x78, ioapic_isr_78); +handle_irq(0x66, ioapic_isr_66); set_ioapic_redir(0x10, 0x78); set_ioapic_redir(0x11, 0x66); irq_disable(); @@ -323,7 +295,7 @@ static void test_sti_nmi(void) return; } -set_idt_entry(2, nmi_handler); +handle_irq(2, nmi_handler); on_cpu(1, update_cr3, (void *)read_cr3()); sti_loop_active = 1; @@ -343,6 +315,7 @@ int main() { setup_vm(); smp_init(); +setup_idt(); test_lapic_existence(); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Move idt.c into lib code
From: Gleb Natapov g...@redhat.com Make it compilable in 32 and 64 bit mode. Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/config-x86-common.mak b/config-x86-common.mak index b5c49f4..4d50e51 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -11,6 +11,7 @@ cflatobjs += \ cflatobjs += lib/x86/fwcfg.o cflatobjs += lib/x86/apic.o cflatobjs += lib/x86/atomic.o +cflatobjs += lib/x86/idt.o $(libcflat): LDFLAGS += -nostdlib $(libcflat): CFLAGS += -ffreestanding -I lib @@ -53,7 +54,7 @@ $(TEST_DIR)/vmexit.elf: $(cstart.o) $(TEST_DIR)/vmexit.o $(TEST_DIR)/smptest.elf: $(cstart.o) $(TEST_DIR)/smptest.o $(TEST_DIR)/emulator.elf: $(cstart.o) $(TEST_DIR)/emulator.o \ - $(TEST_DIR)/vm.o $(TEST_DIR)/idt.o + $(TEST_DIR)/vm.o $(TEST_DIR)/port80.elf: $(cstart.o) $(TEST_DIR)/port80.o @@ -68,9 +69,9 @@ $(TEST_DIR)/realmode.o: bits = 32 $(TEST_DIR)/msr.elf: $(cstart.o) $(TEST_DIR)/msr.o -$(TEST_DIR)/idt_test.elf: $(cstart.o) $(TEST_DIR)/idt.o $(TEST_DIR)/idt_test.o +$(TEST_DIR)/idt_test.elf: $(cstart.o) $(TEST_DIR)/idt_test.o -$(TEST_DIR)/xsave.elf: $(cstart.o) $(TEST_DIR)/idt.o $(TEST_DIR)/xsave.o +$(TEST_DIR)/xsave.elf: $(cstart.o) $(TEST_DIR)/xsave.o $(TEST_DIR)/rmap_chain.elf: $(cstart.o) $(TEST_DIR)/rmap_chain.o \ $(TEST_DIR)/vm.o diff --git a/x86/idt.c b/lib/x86/idt.c similarity index 69% rename from x86/idt.c rename to lib/x86/idt.c index 4480833..b3e47d4 100644 --- a/x86/idt.c +++ b/lib/x86/idt.c @@ -1,5 +1,6 @@ #include idt.h #include libcflat.h +#include processor.h typedef struct { unsigned short offset0; @@ -11,36 +12,27 @@ typedef struct { unsigned short dpl : 2; unsigned short p : 1; unsigned short offset1; +#ifdef __x86_64__ unsigned offset2; unsigned reserved; +#endif } idt_entry_t; static idt_entry_t idt[256]; -typedef struct { -unsigned short limit; -unsigned long linear_addr; -} __attribute__((packed)) descriptor_table_t; - -void lidt(idt_entry_t *idt, int nentries) +void load_lidt(idt_entry_t *idt, int nentries) { -descriptor_table_t dt; +struct descriptor_table_ptr dt; dt.limit = nentries * sizeof(*idt) - 1; -dt.linear_addr = (unsigned long)idt; +dt.base = (unsigned long)idt; +lidt(dt); asm volatile (lidt %0 : : m(dt)); } -unsigned short read_cs() -{ -unsigned short r; - -asm volatile (mov %%cs, %0 : =r(r)); -return r; -} - -void set_idt_entry(idt_entry_t *e, void *addr, int dpl) +void set_idt_entry(int vec, void *addr, int dpl) { +idt_entry_t *e = idt[vec]; memset(e, 0, sizeof *e); e-offset0 = (unsigned long)addr; e-selector = read_cs(); @@ -49,14 +41,18 @@ void set_idt_entry(idt_entry_t *e, void *addr, int dpl) e-dpl = dpl; e-p = 1; e-offset1 = (unsigned long)addr 16; +#ifdef __x86_64__ e-offset2 = (unsigned long)addr 32; +#endif } struct ex_regs { unsigned long rax, rcx, rdx, rbx; unsigned long dummy, rbp, rsi, rdi; +#ifdef __x86_64__ unsigned long r8, r9, r10, r11; unsigned long r12, r13, r14, r15; +#endif unsigned long vector; unsigned long error_code; unsigned long rip; @@ -90,34 +86,49 @@ void do_handle_exception(struct ex_regs *regs) exit(7); } +#ifdef __x86_64__ +# define R r +# define W q +# define S 8 +#else +# define R e +# define W l +# define S 4 +#endif + asm (.pushsection .text \n\t ud_fault: \n\t - pushq $0 \n\t - pushq $6 \n\t + pushW $0 \n\t + pushW $6 \n\t jmp handle_exception \n\t gp_fault: \n\t - pushq $13 \n\t + pushW $13 \n\t jmp handle_exception \n\t de_fault: \n\t - pushq $0 \n\t - pushq $0 \n\t + pushW $0 \n\t + pushW $0 \n\t jmp handle_exception \n\t handle_exception: \n\t +#ifdef __x86_64__ push %r15; push %r14; push %r13; push %r12 \n\t push %r11; push %r10; push %r9; push %r8 \n\t - push %rdi; push %rsi; push %rbp; sub $8, %rsp \n\t - push %rbx; push %rdx; push %rcx; push %rax \n\t - mov %rsp, %rdi \n\t +#endif + push %Rdi; push %Rsi; push %Rbp; sub $S, %Rsp \n\t + push %Rbx; push %Rdx; push %Rcx; push %Rax \n\t + mov %Rsp, %Rdi \n\t call do_handle_exception \n\t - pop %rax; pop %rcx; pop %rdx; pop %rbx \n\t - add $8, %rsp; pop %rbp; pop %rsi; pop %rdi \n\t + pop %Rax; pop %Rcx; pop %Rdx; pop %Rbx \n\t + add $S, %Rsp; pop %Rbp; pop %Rsi; pop %Rdi \n\t +#ifdef __x86_64__ pop %r8; pop %r9; pop %r10; pop %r11 \n\t pop %r12; pop %r13; pop %r14; pop %r15 \n\t - add $16, %rsp \n\t - iretq \n\t +#endif + add $S, %Rsp \n\t + add $S, %Rsp \n\t + iretW \n\t .popsection); @@ -125,10 +136,10 @@ void setup_idt(void) { extern char ud_fault, gp_fault, de_fault; -lidt(idt, 256); -set_idt_entry(idt[0], de_fault, 0); -
[COMMIT master] Remove unused function from apic test
From: Gleb Natapov g...@redhat.com Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/x86/apic.c b/x86/apic.c index 6d06f9f..bcb9fc1 100644 --- a/x86/apic.c +++ b/x86/apic.c @@ -78,11 +78,6 @@ asm ( static int g_fail; static int g_tests; -static void outb(unsigned char data, unsigned short port) -{ -asm volatile (out %0, %1 : : a(data), d(port)); -} - static void report(const char *msg, int pass) { ++g_tests; -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Rename idt.[ch] into desc.[ch]
From: Gleb Natapov g...@redhat.com All descriptor related code will go there. Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/config-x86-common.mak b/config-x86-common.mak index 4d50e51..323da2e 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -11,7 +11,7 @@ cflatobjs += \ cflatobjs += lib/x86/fwcfg.o cflatobjs += lib/x86/apic.o cflatobjs += lib/x86/atomic.o -cflatobjs += lib/x86/idt.o +cflatobjs += lib/x86/desc.o $(libcflat): LDFLAGS += -nostdlib $(libcflat): CFLAGS += -ffreestanding -I lib diff --git a/lib/x86/idt.c b/lib/x86/desc.c similarity index 99% rename from lib/x86/idt.c rename to lib/x86/desc.c index b3e47d4..25a25bc 100644 --- a/lib/x86/idt.c +++ b/lib/x86/desc.c @@ -1,5 +1,5 @@ -#include idt.h #include libcflat.h +#include desc.h #include processor.h typedef struct { diff --git a/lib/x86/idt.h b/lib/x86/desc.h similarity index 100% rename from lib/x86/idt.h rename to lib/x86/desc.h diff --git a/x86/access.c b/x86/access.c index 1c638a7..c643f5c 100644 --- a/x86/access.c +++ b/x86/access.c @@ -1,6 +1,6 @@ #include libcflat.h -#include idt.h +#include desc.h #include processor.h #define smp_id() 0 diff --git a/x86/apic.c b/x86/apic.c index bcb9fc1..4f05b02 100644 --- a/x86/apic.c +++ b/x86/apic.c @@ -2,7 +2,7 @@ #include apic.h #include vm.h #include smp.h -#include idt.h +#include desc.h typedef struct { ulong regs[sizeof(ulong)*2]; diff --git a/x86/emulator.c b/x86/emulator.c index 845e7a0..0486d38 100644 --- a/x86/emulator.c +++ b/x86/emulator.c @@ -1,7 +1,7 @@ #include ioram.h #include vm.h #include libcflat.h -#include idt.h +#include desc.h #define memset __builtin_memset #define TESTDEV_IO_PORT 0xe0 diff --git a/x86/idt_test.c b/x86/idt_test.c index 59256d4..2d2e0c2 100644 --- a/x86/idt_test.c +++ b/x86/idt_test.c @@ -1,5 +1,5 @@ #include libcflat.h -#include idt.h +#include desc.h int test_ud2(void) { diff --git a/x86/xsave.c b/x86/xsave.c index a22b44c..057b0ff 100644 --- a/x86/xsave.c +++ b/x86/xsave.c @@ -1,5 +1,5 @@ #include libcflat.h -#include idt.h +#include desc.h #ifdef __x86_64__ #define uint64_t unsigned long -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Change LTR's operand to be a u16
From: Avi Kivity a...@redhat.com This makes it pick the correct register size. Signed-off-by: Avi Kivity a...@redhat.com diff --git a/lib/x86/processor.h b/lib/x86/processor.h index c348808..d0ace9e 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -191,7 +191,7 @@ static inline u16 sldt(void) return val; } -static inline void ltr(unsigned val) +static inline void ltr(u16 val) { asm volatile (ltr %0 : : rm(val)); } -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Move irq_(enable|disable) into library code
From: Gleb Natapov g...@redhat.com Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/lib/x86/processor.h b/lib/x86/processor.h index d0ace9e..8fb70cd 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -280,4 +280,14 @@ static inline void wrtsc(u64 tsc) asm volatile(wrmsr : : a(a), d(d), c(0x10)); } +static inline void irq_disable(void) +{ +asm volatile(cli); +} + +static inline void irq_enable(void) +{ +asm volatile(sti); +} + #endif diff --git a/x86/apic.c b/x86/apic.c index 4f05b02..3dd2485 100644 --- a/x86/apic.c +++ b/x86/apic.c @@ -134,16 +134,6 @@ static void handle_irq(unsigned vec, void (*func)(isr_regs_t *regs)) #endif } -static void irq_disable(void) -{ -asm volatile(cli); -} - -static void irq_enable(void) -{ -asm volatile(sti); -} - static void eoi(void) { apic_write(APIC_EOI, 0); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Set WP bit in CR0 to make write protection work
From: Gleb Natapov g...@redhat.com Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/lib/x86/vm.c b/lib/x86/vm.c index 4d0a955..1ca8a05 100644 --- a/lib/x86/vm.c +++ b/lib/x86/vm.c @@ -9,6 +9,7 @@ #endif #define X86_CR0_PE 0x0001 +#define X86_CR0_WP 0x0001 #define X86_CR0_PG 0x8000 #define X86_CR4_PSE 0x0010 static void *free = 0; @@ -176,7 +177,7 @@ static void setup_mmu(unsigned long len) #ifndef __x86_64__ write_cr4(X86_CR4_PSE); #endif -write_cr0(X86_CR0_PG |X86_CR0_PE); +write_cr0(X86_CR0_PG |X86_CR0_PE | X86_CR0_WP); printf(paging enabled\n); printf(cr0 = %x\n, read_cr0()); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Fix mmu on 32 bit
From: Gleb Natapov g...@redhat.com The way virtual memory is setup now does not leave space for vmalloc on 32bit system. Make a hole in address space from 2G to 3G for vmalloc on 32 bit. Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/lib/x86/vm.c b/lib/x86/vm.c index b34449f..4d0a955 100644 --- a/lib/x86/vm.c +++ b/lib/x86/vm.c @@ -135,23 +135,43 @@ struct ljmp { unsigned short seg; }; +static void setup_mmu_range(unsigned long *cr3, unsigned long start, + unsigned long len) +{ + u64 max = (u64)len + (u64)start; + u64 phys = start; + + while (phys + LARGE_PAGE_SIZE = max) { + install_large_page(cr3, phys, (void *)(ulong)phys); + phys += LARGE_PAGE_SIZE; + } + while (phys + PAGE_SIZE = max) { + install_page(cr3, phys, (void *)(ulong)phys); + phys += PAGE_SIZE; + } +} + static void setup_mmu(unsigned long len) { unsigned long *cr3 = alloc_page(); -unsigned long phys = 0; +memset(cr3, 0, PAGE_SIZE); + +#ifdef __x86_64__ if (len (1ul 32)) -len = 1ul 32; /* map mmio 1:1 */ +len = (1ul 32); /* map mmio 1:1 */ + +setup_mmu_range(cr3, 0, len); +#else +if (len (1ul 31)) + len = (1ul 31); + +/* 0 - 2G memory, 2G-3G valloc area, 3G-4G mmio */ +setup_mmu_range(cr3, 0, len); +setup_mmu_range(cr3, 3ul 30, (1ul 30)); +vfree_top = (void*)(3ul 30); +#endif -memset(cr3, 0, PAGE_SIZE); -while (phys + LARGE_PAGE_SIZE = len) { - install_large_page(cr3, phys, (void *)phys); - phys += LARGE_PAGE_SIZE; -} -while (phys + PAGE_SIZE = len) { - install_page(cr3, phys, (void *)phys); - phys += PAGE_SIZE; -} write_cr3(virt_to_phys(cr3)); #ifndef __x86_64__ write_cr4(X86_CR4_PSE); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Move vm.[ch] info library code
From: Gleb Natapov g...@redhat.com Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/config-x86-common.mak b/config-x86-common.mak index 323da2e..1e019f1 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -8,6 +8,7 @@ cflatobjs += \ lib/x86/io.o \ lib/x86/smp.o +cflatobjs += lib/x86/vm.o cflatobjs += lib/x86/fwcfg.o cflatobjs += lib/x86/apic.o cflatobjs += lib/x86/atomic.o @@ -46,21 +47,19 @@ $(TEST_DIR)/access.elf: $(cstart.o) $(TEST_DIR)/access.o $(TEST_DIR)/hypercall.elf: $(cstart.o) $(TEST_DIR)/hypercall.o -$(TEST_DIR)/sieve.elf: $(cstart.o) $(TEST_DIR)/sieve.o \ - $(TEST_DIR)/vm.o +$(TEST_DIR)/sieve.elf: $(cstart.o) $(TEST_DIR)/sieve.o $(TEST_DIR)/vmexit.elf: $(cstart.o) $(TEST_DIR)/vmexit.o $(TEST_DIR)/smptest.elf: $(cstart.o) $(TEST_DIR)/smptest.o -$(TEST_DIR)/emulator.elf: $(cstart.o) $(TEST_DIR)/emulator.o \ - $(TEST_DIR)/vm.o +$(TEST_DIR)/emulator.elf: $(cstart.o) $(TEST_DIR)/emulator.o $(TEST_DIR)/port80.elf: $(cstart.o) $(TEST_DIR)/port80.o $(TEST_DIR)/tsc.elf: $(cstart.o) $(TEST_DIR)/tsc.o -$(TEST_DIR)/apic.elf: $(cstart.o) $(TEST_DIR)/apic.o $(TEST_DIR)/vm.o +$(TEST_DIR)/apic.elf: $(cstart.o) $(TEST_DIR)/apic.o $(TEST_DIR)/realmode.elf: $(TEST_DIR)/realmode.o $(CC) -m32 -nostdlib -o $@ -Wl,-T,$(TEST_DIR)/realmode.lds $^ @@ -73,10 +72,9 @@ $(TEST_DIR)/idt_test.elf: $(cstart.o) $(TEST_DIR)/idt_test.o $(TEST_DIR)/xsave.elf: $(cstart.o) $(TEST_DIR)/xsave.o -$(TEST_DIR)/rmap_chain.elf: $(cstart.o) $(TEST_DIR)/rmap_chain.o \ -$(TEST_DIR)/vm.o +$(TEST_DIR)/rmap_chain.elf: $(cstart.o) $(TEST_DIR)/rmap_chain.o -$(TEST_DIR)/svm.elf: $(cstart.o) $(TEST_DIR)/vm.o +$(TEST_DIR)/svm.elf: $(cstart.o) $(TEST_DIR)/kvmclock_test.elf: $(cstart.o) $(TEST_DIR)/kvmclock.o \ $(TEST_DIR)/kvmclock_test.o diff --git a/x86/vm.c b/lib/x86/vm.c similarity index 100% rename from x86/vm.c rename to lib/x86/vm.c diff --git a/x86/vm.h b/lib/x86/vm.h similarity index 100% rename from x86/vm.h rename to lib/x86/vm.h -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Move invlpg() into library code
From: Gleb Natapov g...@redhat.com Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/lib/x86/processor.h b/lib/x86/processor.h index 8fb70cd..f69f9ff 100644 --- a/lib/x86/processor.h +++ b/lib/x86/processor.h @@ -290,4 +290,8 @@ static inline void irq_enable(void) asm volatile(sti); } +static inline void invlpg(void *va) +{ + asm volatile(invlpg (%0) ::r (va) : memory); +} #endif diff --git a/x86/access.c b/x86/access.c index c643f5c..7c8b9a5 100644 --- a/x86/access.c +++ b/x86/access.c @@ -202,11 +202,6 @@ int ac_test_bump(ac_test_t *at) return ret; } -void invlpg(void *addr) -{ -asm volatile (invlpg (%0) : : r(addr)); -} - pt_element_t ac_test_alloc_pt(ac_pool_t *pool) { pt_element_t ret = pool-pt_pool + pool-pt_pool_current; -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Move handle_irq() from apic test into library code
From: Gleb Natapov g...@redhat.com Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/config-x86-common.mak b/config-x86-common.mak index 1e019f1..17769fa 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -13,6 +13,7 @@ cflatobjs += lib/x86/fwcfg.o cflatobjs += lib/x86/apic.o cflatobjs += lib/x86/atomic.o cflatobjs += lib/x86/desc.o +cflatobjs += lib/x86/isr.o $(libcflat): LDFLAGS += -nostdlib $(libcflat): CFLAGS += -ffreestanding -I lib diff --git a/lib/x86/isr.c b/lib/x86/isr.c new file mode 100644 index 000..9986d17 --- /dev/null +++ b/lib/x86/isr.c @@ -0,0 +1,98 @@ +#include libcflat.h +#include isr.h +#include vm.h +#include desc.h + +#ifdef __x86_64__ +# define R r +#else +# define R e +#endif + +extern char isr_entry_point[]; + +asm ( +isr_entry_point: \n +#ifdef __x86_64__ +push %r15 \n\t +push %r14 \n\t +push %r13 \n\t +push %r12 \n\t +push %r11 \n\t +push %r10 \n\t +push %r9 \n\t +push %r8 \n\t +#endif +push %R di \n\t +push %R si \n\t +push %R bp \n\t +push %R sp \n\t +push %R bx \n\t +push %R dx \n\t +push %R cx \n\t +push %R ax \n\t +#ifdef __x86_64__ +mov %rsp, %rdi \n\t +callq *8*16(%rsp) \n\t +#else +push %esp \n\t +calll *4+4*8(%esp) \n\t +add $4, %esp \n\t +#endif +pop %R ax \n\t +pop %R cx \n\t +pop %R dx \n\t +pop %R bx \n\t +pop %R bp \n\t +pop %R bp \n\t +pop %R si \n\t +pop %R di \n\t +#ifdef __x86_64__ +pop %r8 \n\t +pop %r9 \n\t +pop %r10 \n\t +pop %r11 \n\t +pop %r12 \n\t +pop %r13 \n\t +pop %r14 \n\t +pop %r15 \n\t +#endif +.globl isr_iret_ip\n\t +#ifdef __x86_64__ +add $8, %rsp \n\t +isr_iret_ip: \n\t +iretq \n\t +#else +add $4, %esp \n\t +isr_iret_ip: \n\t +iretl \n\t +#endif +); + +void handle_irq(unsigned vec, void (*func)(isr_regs_t *regs)) +{ +u8 *thunk = vmalloc(50); + +set_idt_entry(vec, thunk, 0); + +#ifdef __x86_64__ +/* sub $8, %rsp */ +*thunk++ = 0x48; *thunk++ = 0x83; *thunk++ = 0xec; *thunk++ = 0x08; +/* mov $func_low, %(rsp) */ +*thunk++ = 0xc7; *thunk++ = 0x04; *thunk++ = 0x24; +*(u32 *)thunk = (ulong)func; thunk += 4; +/* mov $func_high, %(rsp+4) */ +*thunk++ = 0xc7; *thunk++ = 0x44; *thunk++ = 0x24; *thunk++ = 0x04; +*(u32 *)thunk = (ulong)func 32; thunk += 4; +/* jmp isr_entry_point */ +*thunk ++ = 0xe9; +*(u32 *)thunk = (ulong)isr_entry_point - (ulong)(thunk + 4); +#else +/* push $func */ +*thunk++ = 0x68; +*(u32 *)thunk = (ulong)func; thunk += 4; +/* jmp isr_entry_point */ +*thunk++ = 0xe9; +*(u32 *)thunk = (ulong)isr_entry_point - (ulong)(thunk + 4); +#endif +} diff --git a/lib/x86/isr.h b/lib/x86/isr.h new file mode 100644 index 000..b07a32a --- /dev/null +++ b/lib/x86/isr.h @@ -0,0 +1,14 @@ +#ifndef __ISR_TEST__ +#define __ISR_TEST__ + +typedef struct { +ulong regs[sizeof(ulong)*2]; +ulong func; +ulong rip; +ulong cs; +ulong rflags; +} isr_regs_t; + +void handle_irq(unsigned vec, void (*func)(isr_regs_t *regs)); + +#endif diff --git a/x86/apic.c b/x86/apic.c index 3dd2485..1366185 100644 --- a/x86/apic.c +++ b/x86/apic.c @@ -3,77 +3,7 @@ #include vm.h #include smp.h #include desc.h - -typedef struct { -ulong regs[sizeof(ulong)*2]; -ulong func; -ulong rip; -ulong cs; -ulong rflags; -} isr_regs_t; - -#ifdef __x86_64__ -# define R r -#else -# define R e -#endif - -extern char isr_entry_point[]; - -asm ( -isr_entry_point: \n -#ifdef __x86_64__ -push %r15 \n\t -push %r14 \n\t -push %r13 \n\t -push %r12 \n\t -push %r11 \n\t -push %r10 \n\t -push %r9 \n\t -push %r8 \n\t -#endif -push %R di \n\t -push %R si \n\t -push %R bp \n\t -push %R sp \n\t -push %R bx \n\t -push %R dx \n\t -push %R cx \n\t -push %R ax \n\t -#ifdef __x86_64__ -mov %rsp, %rdi \n\t -callq *8*16(%rsp) \n\t -#else -push %esp \n\t -calll *4+4*8(%esp) \n\t -add $4, %esp \n\t -#endif -pop %R ax \n\t -pop %R cx \n\t -pop %R dx \n\t -pop %R bx \n\t -pop %R bp \n\t -pop %R bp \n\t -pop %R si \n\t -pop %R di \n\t -#ifdef __x86_64__ -pop %r8 \n\t -pop %r9 \n\t -pop %r10 \n\t -pop %r11 \n\t -pop %r12 \n\t -pop %r13 \n\t -pop %r14 \n\t -pop %r15 \n\t -#endif -#ifdef __x86_64__ -add $8, %rsp \n\t -iretq \n\t -#else -add $4, %esp \n\t -iretl \n\t -#endif -); +#include isr.h static int g_fail; static int g_tests; @@ -106,34 +36,6 @@ void test_enable_x2apic(void) } } -static void handle_irq(unsigned vec, void (*func)(isr_regs_t *regs)) -{ -u8 *thunk = vmalloc(50); - -set_idt_entry(vec, thunk, 0); - -#ifdef __x86_64__ -/* sub $8, %rsp */ -*thunk++ = 0x48; *thunk++ = 0x83; *thunk++ = 0xec; *thunk++ = 0x08; -/* mov
[COMMIT master] Add event injection test
From: Gleb Natapov g...@redhat.com Add various event injection test. Those tests use testdev to unmap pages from shadow pages/ept tables which make it possible to test rare scenarios. [avi: my compiler didn't like fooRbar, added spaces] Signed-off-by: Gleb Natapov g...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/config-x86-common.mak b/config-x86-common.mak index 17769fa..cca8f87 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -33,7 +33,7 @@ tests-common = $(TEST_DIR)/vmexit.flat $(TEST_DIR)/tsc.flat \ $(TEST_DIR)/smptest.flat $(TEST_DIR)/port80.flat \ $(TEST_DIR)/realmode.flat $(TEST_DIR)/msr.flat \ $(TEST_DIR)/hypercall.flat $(TEST_DIR)/sieve.flat \ - $(TEST_DIR)/kvmclock_test.flat + $(TEST_DIR)/kvmclock_test.flat $(TEST_DIR)/eventinj.flat tests-common += api/api-sample tests-common += api/dirty-log @@ -80,6 +80,8 @@ $(TEST_DIR)/svm.elf: $(cstart.o) $(TEST_DIR)/kvmclock_test.elf: $(cstart.o) $(TEST_DIR)/kvmclock.o \ $(TEST_DIR)/kvmclock_test.o +$(TEST_DIR)/eventinj.elf: $(cstart.o) $(TEST_DIR)/eventinj.o + arch_clean: $(RM) $(TEST_DIR)/*.o $(TEST_DIR)/*.flat $(TEST_DIR)/*.elf \ $(TEST_DIR)/.*.d $(TEST_DIR)/lib/.*.d $(TEST_DIR)/lib/*.o diff --git a/lib/x86/desc.c b/lib/x86/desc.c index 0da8989..1bd4421 100644 --- a/lib/x86/desc.c +++ b/lib/x86/desc.c @@ -62,7 +62,7 @@ typedef struct { u16 iomap_base; } tss32_t; -static idt_entry_t idt[256]; +static idt_entry_t idt[256] __attribute__((aligned(4096))); void load_lidt(idt_entry_t *idt, int nentries) { @@ -90,6 +90,11 @@ void set_idt_entry(int vec, void *addr, int dpl) #endif } +void set_idt_sel(int vec, u16 sel) +{ +idt_entry_t *e = idt[vec]; +e-selector = sel; +} struct ex_record { unsigned long rip; diff --git a/lib/x86/desc.h b/lib/x86/desc.h index 073878d..0b4897c 100644 --- a/lib/x86/desc.h +++ b/lib/x86/desc.h @@ -37,9 +37,12 @@ struct ex_regs { #define TSS_MAIN 0x20 #define TSS_INTR 0x28 +#define NP_SEL 0x18 + unsigned exception_vector(void); unsigned exception_error_code(void); void set_idt_entry(int vec, void *addr, int dpl); +void set_idt_sel(int vec, u16 sel); void set_gdt_entry(int num, u32 base, u32 limit, u8 access, u8 gran); void set_intr_task_gate(int e, void *fn); void print_current_tss_info(void); diff --git a/lib/x86/vm.c b/lib/x86/vm.c index 1ca8a05..abbb0c9 100644 --- a/lib/x86/vm.c +++ b/lib/x86/vm.c @@ -248,3 +248,9 @@ void *vmap(unsigned long long phys, unsigned long size) } return mem; } + +void *alloc_vpage(void) +{ + vfree_top -= PAGE_SIZE; + return vfree_top; +} diff --git a/lib/x86/vm.h b/lib/x86/vm.h index a3d2676..bf8fd52 100644 --- a/lib/x86/vm.h +++ b/lib/x86/vm.h @@ -20,6 +20,7 @@ void setup_vm(); void *vmalloc(unsigned long size); void vfree(void *mem); void *vmap(unsigned long long phys, unsigned long size); +void *alloc_vpage(void); void install_pte(unsigned long *cr3, int pte_level, diff --git a/x86/eventinj.c b/x86/eventinj.c new file mode 100644 index 000..7bed7c5 --- /dev/null +++ b/x86/eventinj.c @@ -0,0 +1,372 @@ +#include libcflat.h +#include processor.h +#include vm.h +#include desc.h +#include isr.h +#include apic.h +#include apic-defs.h + +#ifdef __x86_64__ +# define R r +#else +# define R e +#endif + +static int g_fail; +static int g_tests; + +static inline void io_delay(void) +{ +} + +static inline void outl(int addr, int val) +{ +asm volatile (outl %1, %w0 : : d (addr), a (val)); +} + +static void report(const char *msg, int pass) +{ +++g_tests; +printf(%s: %s\n, msg, (pass ? PASS : FAIL)); +if (!pass) +++g_fail; +} + +void apic_self_ipi(u8 v) +{ + apic_icr_write(APIC_DEST_SELF | APIC_DEST_PHYSICAL | APIC_DM_FIXED | + APIC_INT_ASSERT | v, 0); +} + +void apic_self_nmi(void) +{ + apic_icr_write(APIC_DEST_PHYSICAL | APIC_DM_NMI | APIC_INT_ASSERT, 0); +} + +static void eoi(void) +{ +apic_write(APIC_EOI, 0); +} + +#define flush_phys_addr(__s) outl(0xe4, __s) +#define flush_stack() do { \ + int __l;\ + flush_phys_addr(virt_to_phys(__l));\ + } while (0) + +extern char isr_iret_ip[]; + +static void flush_idt_page() +{ + struct descriptor_table_ptr ptr; + sidt(ptr); + flush_phys_addr(virt_to_phys((void*)ptr.base)); +} + +static volatile unsigned int test_divider; +static volatile int test_count; + +#ifndef __x86_64__ +ulong stack_phys; +void *stack_va; + +static void pf_tss(void) +{ +start: + printf(PF running\n); + install_pte(phys_to_virt(read_cr3()), 1, stack_va, + stack_phys | PTE_PRESENT | PTE_WRITE, 0); + invlpg(stack_va); + asm volatile (iret); + goto start;
Re: [COMMIT master] KVM guest: Fix kvm clock initialization when it's configured out
On Sun, Dec 19, 2010 at 1:50 PM, Avi Kivity a...@redhat.com wrote: From: Avi Kivity a...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com Avi, I recently sent a patch that handles a case much similar to this: when kvmclock is compiled in the guest, but not enabled in the host. It somehow seem to have been lost? -- Sent from my Casio Solar Calculator. -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] pci: Fix PCI capabilities collision error value
From: Alex Williamson alex.william...@redhat.com Signed-off-by: Alex Williamson alex.william...@redhat.com Acked-by: Markus Armbruster arm...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/hw/pci.c b/hw/pci.c index 288d6fd..0962416 100644 --- a/hw/pci.c +++ b/hw/pci.c @@ -1856,7 +1856,7 @@ int pci_add_capability(PCIDevice *pdev, uint8_t cap_id, pci_find_domain(pdev-bus), pci_bus_num(pdev-bus), PCI_SLOT(pdev-devfn), PCI_FUNC(pdev-devfn), cap_id, offset, pdev-config_map[i], i); -return -EFAULT; +return -EINVAL; } } } -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] fix compile error of hw/device-assignment.c
From: Wei Yongjun yj...@cn.fujitsu.com Fix the following compile error in next tree: CCx86_64-softmmu/device-assignment.o hw/device-assignment.c: In function ‘assigned_device_pci_cap_init’: hw/device-assignment.c:1463: error: ‘PCI_PM_CTRL_NO_SOFT_RST’ undeclared (first use in this function) hw/device-assignment.c:1463: error: (Each undeclared identifier is reported only once hw/device-assignment.c:1463: error: for each function it appears in.) Signed-off-by: Wei Yongjun yj...@cn.fujitsu.com Acked-by: Alex Williamson alex.william...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 50c6408..8446cd4 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -1460,7 +1460,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) /* assign_device will bring the device up to D0, so we don't need * to worry about doing that ourselves here. */ pci_set_word(pci_dev-config + pos + PCI_PM_CTRL, - PCI_PM_CTRL_NO_SOFT_RST); + PCI_PM_CTRL_NO_SOFT_RESET); pci_set_byte(pci_dev-config + pos + PCI_PM_PPB_EXTENSIONS, 0); pci_set_byte(pci_dev-config + pos + PCI_PM_DATA_REGISTER, 0); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: Correct kvm_pio tracepoint count field
From: Avi Kivity a...@redhat.com Currently, we record '1' for count regardless of the real count. Fix. Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8d76150..cf5fab1 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3948,7 +3948,7 @@ static int emulator_pio_in_emulated(int size, unsigned short port, void *val, if (vcpu-arch.pio.count) goto data_avail; - trace_kvm_pio(0, port, size, 1); + trace_kvm_pio(0, port, size, count); vcpu-arch.pio.port = port; vcpu-arch.pio.in = 1; @@ -3976,7 +3976,7 @@ static int emulator_pio_out_emulated(int size, unsigned short port, const void *val, unsigned int count, struct kvm_vcpu *vcpu) { - trace_kvm_pio(1, port, size, 1); + trace_kvm_pio(1, port, size, count); vcpu-arch.pio.port = port; vcpu-arch.pio.in = 0; -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: return true when user space query KVM_CAP_USER_NMI extension
From: Lai Jiangshan la...@cn.fujitsu.com userspace may check this extension in runtime. Signed-off-by: Lai Jiangshan la...@cn.fujitsu.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index cf5fab1..3625779 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1941,6 +1941,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_NOP_IO_DELAY: case KVM_CAP_MP_STATE: case KVM_CAP_SYNC_MMU: + case KVM_CAP_USER_NMI: case KVM_CAP_REINJECT_CONTROL: case KVM_CAP_IRQ_INJECT_STATUS: case KVM_CAP_ASSIGN_DEV_IRQ: -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM guest: Fix kvm clock initialization when it's configured out
From: Avi Kivity a...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 91b3d65..8dc4466 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -486,7 +486,9 @@ static struct notifier_block kvm_pv_reboot_nb = { #ifdef CONFIG_SMP static void __init kvm_smp_prepare_boot_cpu(void) { +#ifdef CONFIG_KVM_CLOCK WARN_ON(kvm_register_clock(primary cpu clock)); +#endif kvm_guest_cpu_init(); native_smp_prepare_boot_cpu(); } -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: Fix whitespace errors
From: Avi Kivity a...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 5bc820c..c3853d5 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -2644,7 +2644,7 @@ static bool try_async_pf(struct kvm_vcpu *vcpu, bool prefault, gfn_t gfn, } *pfn = gfn_to_pfn_prot(vcpu-kvm, gfn, write, writable); - + return false; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0301258..e0bd952 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1092,7 +1092,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) tsc_timestamp = tsc; } } - + local_irq_restore(flags); if (!vcpu-time_page) @@ -5341,7 +5341,7 @@ static int __vcpu_run(struct kvm_vcpu *vcpu) vcpu-run-exit_reason = KVM_EXIT_INTR; ++vcpu-stat.request_irq_exits; } - + kvm_check_async_pf_completion(vcpu); if (signal_pending(current)) { diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 83f5bf6..b1b6cbb 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1349,7 +1349,7 @@ int kvm_write_guest_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc, if (slots-generation != ghc-generation) kvm_gfn_to_hva_cache_init(kvm, ghc, ghc-gpa); - + if (kvm_is_error_hva(ghc-hva)) return -EFAULT; -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] KVM: Fix preemption counter leak in kvm_timer_init()
From: Avi Kivity a...@redhat.com Based on a patch from Thomas Meyer. Signed-off-by: Avi Kivity a...@redhat.com diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index e0bd952..f569da8 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -4622,9 +4622,11 @@ static void kvm_timer_init(void) #ifdef CONFIG_CPU_FREQ struct cpufreq_policy policy; memset(policy, 0, sizeof(policy)); - cpufreq_get_policy(policy, get_cpu()); + cpu = get_cpu(); + cpufreq_get_policy(policy, cpu); if (policy.cpuinfo.max_freq) max_tsc_khz = policy.cpuinfo.max_freq; + put_cpu(); #endif cpufreq_register_notifier(kvmclock_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] Merge branch 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into next
From: Avi Kivity a...@redhat.com * 'master' of ssh://master.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6: (332 commits) arch/tile: handle rt_sigreturn() more cleanly arch/tile: handle CLONE_SETTLS in copy_thread(), not user space MIPS: Fix build errors in sc-mips.c x86: avoid high BIOS area when allocating address space x86: avoid E820 regions when allocating address space x86: avoid low BIOS area when allocating address space resources: add arch hook for preventing allocation in reserved areas Revert resources: support allocating space within a region from the top down Revert PCI: allocate bus resources from the top down Revert x86/PCI: allocate space from the end of a region, not the beginning Revert x86: allocate space within a region top-down Revert PCI: fix pci_bus_alloc_resource() hang, prefer positive decode ALSA: hda - Fix conflict of Mic Boot controls at91: Refactor Stamp9G20 and PControl G20 board file at91: Fix uhpck clock rate in upll case PCI: Update MCP55 quirk to not affect non HyperTransport variants MIPS: Add a CONFIG_FORCE_MAX_ZONEORDER Kconfig option. MIPS: LD/SD o32 macro GAS fix update MIPS: Alchemy: fix build with SERIAL_8250=n MIPS: Rename mips_dma_cache_sync back to dma_cache_sync ... Conflicts: arch/x86/kvm/x86.c Signed-off-by: Avi Kivity a...@redhat.com -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] fix i386 arch compilation.
From: Gleb Natapov g...@redhat.com Commit 750bbdb forgot to convert i386 arch to .elf. Signed-off-by: Avi Kivity a...@redhat.com diff --git a/config-i386.mak b/config-i386.mak index 6dbd19f..c1b6e08 100644 --- a/config-i386.mak +++ b/config-i386.mak @@ -9,4 +9,4 @@ tests = $(TEST_DIR)/taskswitch.flat include config-x86-common.mak -$(TEST_DIR)/taskswitch.flat: $(cstart.o) $(TEST_DIR)/taskswitch.o +$(TEST_DIR)/taskswitch.elf: $(cstart.o) $(TEST_DIR)/taskswitch.o -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] device-assignment: Fix off-by-one in header check
From: Alex Williamson alex.william...@redhat.com Include the first byte at 40h or else access might go to the hardware instead of the emulated config space, resulting in capability loops, since the ordering is different. Signed-off-by: Alex Williamson alex.william...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 832c236..6d6e657 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -410,7 +410,7 @@ static void assigned_dev_pci_write_config(PCIDevice *d, uint32_t address, ((d-devfn 3) 0x1F), (d-devfn 0x7), (uint16_t) address, val, len); -if (address PCI_CONFIG_HEADER_SIZE d-config_map[address]) { +if (address = PCI_CONFIG_HEADER_SIZE d-config_map[address]) { return assigned_device_pci_cap_write_config(d, address, val, len); } @@ -456,7 +456,7 @@ static uint32_t assigned_dev_pci_read_config(PCIDevice *d, uint32_t address, if (address 0x4 || (pci_dev-need_emulate_cmd address == 0x4) || (address = 0x10 address = 0x24) || address == 0x30 || address == 0x34 || address == 0x3c || address == 0x3d || -(address PCI_CONFIG_HEADER_SIZE d-config_map[address])) { +(address = PCI_CONFIG_HEADER_SIZE d-config_map[address])) { val = pci_default_read_config(d, address, len); DEBUG((%x.%x): address=%04x val=0x%08x len=%d\n, (d-devfn 3) 0x1F, (d-devfn 0x7), address, val, len); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[COMMIT master] pci: Remove PCI_CAPABILITY_CONFIG_*
From: Alex Williamson alex.william...@redhat.com Half of these aren't used anywhere, the other half are wrong. Now that device assignment is trying to match physical hardware offsets for PCI capabilities, we can't round up the MSI and MSI-X length. MSI-X is always 12 bytes. MSI is variable length depending on features, but for the current device assignment implementation, it's always the minimum length of 10 bytes. Signed-off-by: Alex Williamson alex.william...@redhat.com Signed-off-by: Avi Kivity a...@redhat.com diff --git a/hw/device-assignment.c b/hw/device-assignment.c index 6d6e657..1a90a89 100644 --- a/hw/device-assignment.c +++ b/hw/device-assignment.c @@ -1302,10 +1302,9 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) * MSI capability is the 1st capability in capability config */ if ((pos = pci_find_cap_offset(pci_dev, PCI_CAP_ID_MSI))) { dev-cap.available |= ASSIGNED_DEVICE_CAP_MSI; -pci_add_capability(pci_dev, PCI_CAP_ID_MSI, pos, - PCI_CAPABILITY_CONFIG_MSI_LENGTH); - /* Only 32-bit/no-mask currently supported */ +pci_add_capability(pci_dev, PCI_CAP_ID_MSI, pos, 10); + pci_set_word(pci_dev-config + pos + PCI_MSI_FLAGS, pci_get_word(pci_dev-config + pos + PCI_MSI_FLAGS) PCI_MSI_FLAGS_QMASK); @@ -1326,8 +1325,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) uint32_t msix_table_entry; dev-cap.available |= ASSIGNED_DEVICE_CAP_MSIX; -pci_add_capability(pci_dev, PCI_CAP_ID_MSIX, pos, - PCI_CAPABILITY_CONFIG_MSIX_LENGTH); +pci_add_capability(pci_dev, PCI_CAP_ID_MSIX, pos, 12); pci_set_word(pci_dev-config + pos + PCI_MSIX_FLAGS, pci_get_word(pci_dev-config + pos + PCI_MSIX_FLAGS) diff --git a/hw/pci.h b/hw/pci.h index 34955d8..d579738 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -122,11 +122,6 @@ enum { QEMU_PCI_CAP_MULTIFUNCTION = (1 QEMU_PCI_CAP_MULTIFUNCTION_BITNR), }; -#define PCI_CAPABILITY_CONFIG_MAX_LENGTH 0x60 -#define PCI_CAPABILITY_CONFIG_DEFAULT_START_ADDR 0x40 -#define PCI_CAPABILITY_CONFIG_MSI_LENGTH 0x10 -#define PCI_CAPABILITY_CONFIG_MSIX_LENGTH 0x10 - typedef int (*msix_mask_notifier_func)(PCIDevice *, unsigned vector, int masked); -- To unsubscribe from this list: send the line unsubscribe kvm-commits in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html