Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions NetKVM/Common/ParaNdis-TX.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class CNB : public CNdisAllocatableViaHelper<CNB>

ULONG GetSGLLength() const
{
return m_SGL->NumberOfElements;
return m_SGL ? m_SGL->NumberOfElements : 1;
}

NBMappingStatus BindToDescriptor(CTXDescriptor &Descriptor);
Expand Down Expand Up @@ -263,6 +263,7 @@ class CNBL : public CNdisAllocatableViaHelper<CNBL>, public CRefCountingObject,
// TODO: Needs review
void NBComplete();
bool IsSendDone();
bool CheckMappingNeeded();

UCHAR ProtocolID()
{
Expand Down Expand Up @@ -338,6 +339,10 @@ class CNBL : public CNdisAllocatableViaHelper<CNBL>, public CRefCountingObject,
{
return m_NBL != nullptr;
}
bool MappingNeeded() const
{
return !m_SkipMapping;
}
ULONG NumberOfBuffers() const
{
return m_BuffersNumber;
Expand Down Expand Up @@ -396,6 +401,7 @@ class CNBL : public CNdisAllocatableViaHelper<CNBL>, public CRefCountingObject,
ULONG_PTR m_CNB_Storage[(sizeof(CNB) + sizeof(ULONG_PTR) - 1) / sizeof(ULONG_PTR)];
bool m_HaveFailedMappings = false;
bool m_AllNBCompleted = false;
bool m_SkipMapping = false;

CNdisList<CNB, CRawAccess, CNonCountingObject> m_Buffers;

Expand All @@ -417,7 +423,9 @@ class CNBL : public CNdisAllocatableViaHelper<CNBL>, public CRefCountingObject,
#endif
CAllocationHelper<CNB> *m_NBAllocator;

#if NBL_MAINTAIN_HISTORY
CHistoryList m_History;
#endif

CChainOfNbls m_Chain = {};

Expand Down Expand Up @@ -481,7 +489,10 @@ class CParaNdisTX : public CParaNdisTemplatePath<CTXVirtQueue>, public CNdisAllo
bool BorrowPages(CExtendedNBStorage *extraNBStorage, ULONG NeedPages);
void ReturnPages(CExtendedNBStorage *extraNBStorage);
void CheckStuckPackets(ULONG GraceTimeMillies);

ULONG MaxSizeForPacketData()
{
return m_VirtQueue.GetMaxSizeForPacketData();
}
private:
virtual void Notify(SMNotifications message) override;

Expand Down
6 changes: 6 additions & 0 deletions NetKVM/Common/ParaNdis-VirtQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,11 @@ class CTXVirtQueue : public CVirtQueue
return m_TotalDescriptors;
}

ULONG GetMaxSizeForPacketData() const
{
return m_MaxSizeForPacketData;
}

// TODO: Needs review
void Shutdown();

Expand All @@ -375,6 +380,7 @@ class CTXVirtQueue : public CVirtQueue
void FreeBuffers();
ULONG m_MaxBuffers = 0;
ULONG m_HeaderSize = 0;
ULONG m_MaxSizeForPacketData = 0;

void KickQueueOnOverflow();
void UpdateTXStats(const CNB &NB, CTXDescriptor &Descriptor);
Expand Down
41 changes: 34 additions & 7 deletions NetKVM/Common/ParaNdis_TX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ CNBL::~CNBL()
}
}

#if NBL_MAINTAIN_HISTORY
m_History.ForEachDetached([this](NBLHistory *Entry) { NBLHistory::Destroy(Entry, m_Context->MiniportHandle); });
#endif
}

bool CNBL::ParsePriority()
Expand Down Expand Up @@ -305,18 +307,38 @@ bool CNBL::ParseOffloads()
return true;
}

bool CNBL::CheckMappingNeeded()
{
// checksums are excluded for simplicity
// if the packet is short, without LSO, CSO and USO, any layout is ok
// then no need to map it
// TODO: + driver verifier? + DMAR
bool bNoMap = m_MaxDataLength < m_ParentTXPath->MaxSizeForPacketData() && !IsLSO();
bNoMap = bNoMap && !m_CsoInfo.Value && !IsUSO() && m_Context->bAnyLayout;
m_SkipMapping = bNoMap;
return !m_SkipMapping;
}

void CNBL::StartMapping()
{
CDpcIrqlRaiser OnDpc;
bool bMappingNeeded = CheckMappingNeeded();

AddRef();

m_Buffers.ForEach([this](CNB *NB) {
if (!NB->ScheduleBuildSGListForTx())
m_Buffers.ForEach([&](CNB *NB) {
if (!bMappingNeeded)
{
m_HaveFailedMappings = true;
NB->MappingDone(nullptr);
}
else
{
if (!NB->ScheduleBuildSGListForTx())
{
m_HaveFailedMappings = true;
NB->MappingDone(nullptr);
}
}
});

Release();
Expand Down Expand Up @@ -1224,7 +1246,12 @@ NBMappingStatus CNB::FillDescriptorSGList(CTXDescriptor &Descriptor, ULONG Parse
{
return NBMappingStatus::FAILURE;
}
if (Descriptor.HasRoom(m_SGL->NumberOfElements))
if (ParsedHeadersLength == GetDataLength())
{
m_Context->extraStatistics.copiedTxPackets++;
return NBMappingStatus::SUCCESS;
}
if (m_SGL && Descriptor.HasRoom(m_SGL->NumberOfElements))
{
return MapDataToVirtioSGL(Descriptor, ParsedHeadersLength + NET_BUFFER_DATA_OFFSET(m_NB));
}
Expand Down Expand Up @@ -1293,8 +1320,8 @@ bool CNB::CopyHeaders(PVOID Destination, ULONG MaxSize, ULONG &HeadersLength, UL
}
else
{
HeadersLength = ETH_HEADER_SIZE;
Copy(Destination, HeadersLength);
HeadersLength = m_ParentNBL->MappingNeeded() ? ETH_HEADER_SIZE : MaxSize;
HeadersLength = Copy(Destination, HeadersLength);
}

return (HeadersLength <= MaxSize);
Expand Down Expand Up @@ -1353,7 +1380,7 @@ void CNB::Report(int level, bool Success)

NBMappingStatus CNB::BindToDescriptor(CTXDescriptor &Descriptor)
{
if (m_SGL == nullptr)
if (m_SGL == nullptr && m_ParentNBL->MappingNeeded())
{
return NBMappingStatus::FAILURE;
}
Expand Down
5 changes: 5 additions & 0 deletions NetKVM/Common/ParaNdis_VirtQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ bool CTXVirtQueue::PrepareBuffers()
}

m_Descriptors.Push(TXDescr);
// save maximal size of packet than can be placed in the headera area
if (m_TotalDescriptors == 0)
{
m_MaxSizeForPacketData = TXDescr->HeadersAreaAccessor().MaxEthHeadersSize();
}
}

m_FreeHWBuffers = m_TotalHWBuffers = m_TotalDescriptors;
Expand Down
4 changes: 3 additions & 1 deletion NetKVM/ProtocolService/Log.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#pragma once

extern FILE *LogFile;

#define ELEMENTS_IN(a) sizeof(a) / sizeof(a[0])
#define Log(fmt, ...) \
{ \
CStringA _s_; \
_s_.Format(fmt "\n", __VA_ARGS__); \
OutputDebugStringA(_s_); \
if (!LogFile) { OutputDebugStringA(_s_); } else { fwrite(_s_.GetString(), 1, _s_.GetLength(), LogFile); } \
}
3 changes: 2 additions & 1 deletion NetKVM/ProtocolService/Names.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,6 @@ typedef enum _tBindingState
bsUnbindTcpip,
bsBindTcpip,
bsBindNone,
bsBindNoChange
bsBindNoChange,
bsCollectProtocols
} tBindingState;
58 changes: 56 additions & 2 deletions NetKVM/ProtocolService/ProtocolService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,27 @@
#define SERVICE_EXEFILE L"netkvmps.exe"
#define SERVICE_ORGFILE L"netkvmp.exe"

FILE *LogFile;
CAtlArray<CStringA> ListOfTestProtocols;

void AddToList(LPWSTR protocol)
{
CStringA s;
s.Format("%S", protocol);
if (s.Find("ndistest") == 0)
{
auto &l = ListOfTestProtocols;
for (int i = 0; i < l.GetCount(); ++i)
{
if (!s.Compare(l[i]))
{
return;
}
}
l.Add(s);
}
}

class CNetCfg
{
public:
Expand Down Expand Up @@ -228,6 +249,10 @@ class CNetCfg
case bsBindNoChange:
bShouldBeEnabled = enabled;
break;
case bsCollectProtocols:
bShouldBeEnabled = enabled;
AddToList(upperId);
break;
case bsBindAll:
default:
bShouldBeEnabled = true;
Expand Down Expand Up @@ -353,9 +378,9 @@ class CInterfaceTable
{
CheckBinding(Index, NULL, true, State, false);
}
void Dump()
void Dump(tBindingState st = bsBindNoChange)
{
TraverseTable(INFINITE, NULL, false, bsBindNoChange, false, [](const MIB_IF_ROW2 &row) {
TraverseTable(INFINITE, NULL, false, st, false, [](const MIB_IF_ROW2 &row) {
CMACString sMac(row.PhysicalAddress);
auto &fl = row.InterfaceAndOperStatusFlags;
Log("[%s] hw %d, paused %d, lp %d, %s",
Expand Down Expand Up @@ -1255,6 +1280,35 @@ int __cdecl main(int argc, char **argv)
CInterfaceTable t;
t.Dump();
}
else if (!s.CompareNoCase("l") || !s.CompareNoCase("z"))
{
bool remove = !s.CompareNoCase("z");
const char *fname = "c:\\netkvmp.log";
fopen_s(&LogFile, fname, "a+b");
if (LogFile)
{
printf("Dumping interface table to %s\n", fname);
CInterfaceTable t;
if (!remove)
{
t.Dump();
}
else
{
t.Dump(bsCollectProtocols);
auto &l = ListOfTestProtocols;
for (int i = 0; i < l.GetCount(); ++i)
{
printf("removing %s\n", l[i].GetString());
CStringA cmd = "netcfg -v -u ";
cmd += l[i];
system(cmd);
}
}
fclose(LogFile);
LogFile = NULL;
}
}
else
{
Usage();
Expand Down
2 changes: 1 addition & 1 deletion NetKVM/netkvm-base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ HKR, , TypesSupported, 0x00010001, 7
HKR,,TextModeFlags,0x00010001, 0x0001
HKR,Parameters,DisableMSI,,"0"
HKR,Parameters,EarlyDebug,,"3"
HKR,Parameters,DmaRemappingCompatible,0x00010001,INX_NETKVM_DMAREMAP
HKR,Parameters,DmaRemappingCompatible,0x00010001,2


[SourceDisksNames]
Expand Down
Loading