Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,14 @@ public class DifferentialSeqCallGraphAnalysis extends TmfAbstractAnalysisModule
*/
public DifferentialSeqCallGraphAnalysis() {
super();

// TODO: Make a way to register tracetype->callstack IDs.
fCallStackAnalysisMap.put("org.eclipse.tracecompass.incubator.traceevent.core.trace", "org.eclipse.tracecompass.incubator.traceevent.analysis.callstack"); //$NON-NLS-1$ //$NON-NLS-2$
fCallStackAnalysisMap.put("org.eclipse.linuxtools.lttng2.ust.tracetype", "org.eclipse.tracecompass.lttng2.ust.core.analysis.callstack"); //$NON-NLS-1$ //$NON-NLS-2$

// Adding VM/Native analysis
fCallStackAnalysisMap.put("org.eclipse.linuxtools.lttng2.kernel.tracetype", //$NON-NLS-1$
"org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis.vm.native.callstack"); //$NON-NLS-1$
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Require-Bundle: org.eclipse.core.runtime,
Export-Package: org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core;x-internal:=true,
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.data;x-friends:="org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests,org.eclipse.tracecompass.incubator.virtual.machine.analysis.ui",
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.event.matching;x-internal:=true,
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis.core.data.provider;x-friends:="org.eclipse.tracecompass.incubator.virtual.machine.analysis.ui",
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.fused;x-friends:="org.eclipse.tracecompass.incubator.virtual.machine.analysis.ui,org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests",
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.fused.handlers;x-friends:="org.eclipse.tracecompass.incubator.virtual.machine.analysis.ui,org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests",
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.model;x-friends:="org.eclipse.tracecompass.incubator.virtual.machine.analysis.core.tests,org.eclipse.tracecompass.incubator.virtual.machine.analysis.ui",
Expand All @@ -35,5 +36,6 @@ Export-Package: org.eclipse.tracecompass.incubator.internal.virtual.machine.anal
org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.virtual.resources.handlers;x-internal:=true
Import-Package: com.google.common.collect,
com.google.common.hash,
com.google.common.primitives
com.google.common.primitives,
org.eclipse.tracecompass.internal.lttng2.kernel.core.trace.layout
Automatic-Module-Name: org.eclipse.tracecompass.incubator.virtual.machine.analysis.core
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,33 @@
class="org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.trace.VirtualMachineExperiment">
</tracetype>
</module>

<module
analysis_module="org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis.KvmExitAnalysisModule"
automatic="false"
id="org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis.state.system.module"
name="Exit analysis">
<tracetype
applies="true"
class="org.eclipse.tracecompass.tmf.core.trace.TmfTrace">
</tracetype>
Comment thread
beliosien marked this conversation as resolved.
</module>
<module
analysis_module="org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis.VMNativeCallStackAnalysis"
applies_experiment="true"
automatic="false"
id="org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis.vm.native.callstack"
name="VM Native CallStack">
<tracetype
class="org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace">
</tracetype>
</module>
</extension>
<extension
point="org.eclipse.tracecompass.tmf.core.dataprovider">
<dataProviderFactory
class="org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis.core.data.provider.KvmExitRateDataProviderFactory"
id="org.eclipse.incubator.overhead.xy.rate.dataprovider">
</dataProviderFactory>
</extension>
</plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*******************************************************************************
* Copyright (c) 2026 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis;

import java.util.ArrayList;
import java.util.List;

/**
* Represents a complete execution sequence in a virtualized environment:
* <pre>
* VM ENTRY → GUEST → VM EXIT → Hypervisor (Host) → VM Entry
* </pre>
* <p>
* This class aggregates events occurring in both the guest and the hypervisor,
* as well as the VM exit and entry transitions that connect them.
* </p>
*
* @author Francois Belias
*/
public class ExecutionSequence {

/**
* List of events that occurred in the guest before the VM exit.
*/
private final List<FlowEvent> fGuestEvents = new ArrayList<>();

/**
* List of events that occurred in the hypervisor (host)
* between VM exit and VM entry.
*/
private final List<FlowEvent> fHypervisorEvents = new ArrayList<>();

/**
* Event representing the VM exit (transition from guest to host).
*/
private FlowEvent fVmExit;

/**
* Event representing the VM entry (transition from host back to guest).
*/
private FlowEvent fVmEntry;

/**
* Adds an event to the guest event list.
*
* @param event
* the guest event to add
*/
void addGuestEvent(FlowEvent event) {
fGuestEvents.add(event);
}

/**
* Adds an event to the hypervisor event list.
*
* @param event
* the hypervisor event to add
*/
void addHypervisorEvent(FlowEvent event) {
fHypervisorEvents.add(event);
}

/**
* Sets the VM exit event.
*
* @param event
* the VM exit event
*/
void setVmExit(FlowEvent event) {
this.fVmExit = event;
}

/**
* Sets the VM entry event.
*
* @param event
* the VM entry event
*/
void setVmEntry(FlowEvent event) {
this.fVmEntry = event;
}

/**
* Indicates whether the execution sequence is complete.
* <p>
* A sequence is considered complete if it contains:
* <ul>
* <li>At least one guest event</li>
* <li>A VM exit event</li>
* <li>A VM entry event</li>
* </ul>
* </p>
*
* @return {@code true} if the sequence is complete, {@code false} otherwise
*/
boolean isComplete() {
return !fGuestEvents.isEmpty() && fVmExit != null && fVmEntry != null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*******************************************************************************
* Copyright (c) 2026 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis;

import java.util.HashMap;
import java.util.Map;


/**
* Mapping of Exit reason number to their text description
*
* @author Francois Belias
*/
public class ExitReasonMap {

private static final Map<Integer, String> fExitReasonMap = new HashMap<>();

static {
// VMX specific reasons
fExitReasonMap.put(0x80000000, "VMX_EXIT_REASONS_FAILED_VMENTRY"); //$NON-NLS-1$
fExitReasonMap.put(0x08000000, "VMX_EXIT_REASONS_SGX_ENCLAVE_MODE"); //$NON-NLS-1$

// General exit reasons
fExitReasonMap.put(0, "EXIT_REASON_EXCEPTION_NMI"); //$NON-NLS-1$
fExitReasonMap.put(1, "EXIT_REASON_EXTERNAL_INTERRUPT"); //$NON-NLS-1$
fExitReasonMap.put(2, "EXIT_REASON_TRIPLE_FAULT"); //$NON-NLS-1$
fExitReasonMap.put(3, "EXIT_REASON_INIT_SIGNAL"); //$NON-NLS-1$
fExitReasonMap.put(4, "EXIT_REASON_SIPI_SIGNAL"); //$NON-NLS-1$

fExitReasonMap.put(7, "EXIT_REASON_INTERRUPT_WINDOW"); //$NON-NLS-1$
fExitReasonMap.put(8, "EXIT_REASON_NMI_WINDOW"); //$NON-NLS-1$
fExitReasonMap.put(9, "EXIT_REASON_TASK_SWITCH"); //$NON-NLS-1$
fExitReasonMap.put(10, "EXIT_REASON_CPUID"); //$NON-NLS-1$
fExitReasonMap.put(12, "EXIT_REASON_HLT"); //$NON-NLS-1$
fExitReasonMap.put(13, "EXIT_REASON_INVD"); //$NON-NLS-1$
fExitReasonMap.put(14, "EXIT_REASON_INVLPG"); //$NON-NLS-1$
fExitReasonMap.put(15, "EXIT_REASON_RDPMC"); //$NON-NLS-1$
fExitReasonMap.put(16, "EXIT_REASON_RDTSC"); //$NON-NLS-1$
fExitReasonMap.put(18, "EXIT_REASON_VMCALL"); //$NON-NLS-1$
fExitReasonMap.put(19, "EXIT_REASON_VMCLEAR"); //$NON-NLS-1$
fExitReasonMap.put(20, "EXIT_REASON_VMLAUNCH"); //$NON-NLS-1$
fExitReasonMap.put(21, "EXIT_REASON_VMPTRLD"); //$NON-NLS-1$
fExitReasonMap.put(22, "EXIT_REASON_VMPTRST"); //$NON-NLS-1$
fExitReasonMap.put(23, "EXIT_REASON_VMREAD"); //$NON-NLS-1$
fExitReasonMap.put(24, "EXIT_REASON_VMRESUME"); //$NON-NLS-1$
fExitReasonMap.put(25, "EXIT_REASON_VMWRITE"); //$NON-NLS-1$
fExitReasonMap.put(26, "EXIT_REASON_VMOFF"); //$NON-NLS-1$
fExitReasonMap.put(27, "EXIT_REASON_VMON"); //$NON-NLS-1$
fExitReasonMap.put(28, "EXIT_REASON_CR_ACCESS"); //$NON-NLS-1$
fExitReasonMap.put(29, "EXIT_REASON_DR_ACCESS"); //$NON-NLS-1$
fExitReasonMap.put(30, "EXIT_REASON_IO_INSTRUCTION"); //$NON-NLS-1$
fExitReasonMap.put(31, "EXIT_REASON_MSR_READ"); //$NON-NLS-1$
fExitReasonMap.put(32, "EXIT_REASON_MSR_WRITE"); //$NON-NLS-1$
fExitReasonMap.put(33, "EXIT_REASON_INVALID_STATE"); //$NON-NLS-1$
fExitReasonMap.put(34, "EXIT_REASON_MSR_LOAD_FAIL"); //$NON-NLS-1$
fExitReasonMap.put(36, "EXIT_REASON_MWAIT_INSTRUCTION"); //$NON-NLS-1$
fExitReasonMap.put(37, "EXIT_REASON_MONITOR_TRAP_FLAG"); //$NON-NLS-1$
fExitReasonMap.put(39, "EXIT_REASON_MONITOR_INSTRUCTION"); //$NON-NLS-1$
fExitReasonMap.put(40, "EXIT_REASON_PAUSE_INSTRUCTION"); //$NON-NLS-1$
fExitReasonMap.put(41, "EXIT_REASON_MCE_DURING_VMENTRY"); //$NON-NLS-1$
fExitReasonMap.put(43, "EXIT_REASON_TPR_BELOW_THRESHOLD"); //$NON-NLS-1$
fExitReasonMap.put(44, "EXIT_REASON_APIC_ACCESS"); //$NON-NLS-1$
fExitReasonMap.put(45, "EXIT_REASON_EOI_INDUCED"); //$NON-NLS-1$
fExitReasonMap.put(46, "EXIT_REASON_GDTR_IDTR"); //$NON-NLS-1$
fExitReasonMap.put(47, "EXIT_REASON_LDTR_TR"); //$NON-NLS-1$
fExitReasonMap.put(48, "EXIT_REASON_EPT_VIOLATION"); //$NON-NLS-1$
fExitReasonMap.put(49, "EXIT_REASON_EPT_MISCONFIG"); //$NON-NLS-1$
fExitReasonMap.put(50, "EXIT_REASON_INVEPT"); //$NON-NLS-1$
fExitReasonMap.put(51, "EXIT_REASON_RDTSCP"); //$NON-NLS-1$
fExitReasonMap.put(52, "EXIT_REASON_PREEMPTION_TIMER"); //$NON-NLS-1$
fExitReasonMap.put(53, "EXIT_REASON_INVVPID"); //$NON-NLS-1$
fExitReasonMap.put(54, "EXIT_REASON_WBINVD"); //$NON-NLS-1$
fExitReasonMap.put(55, "EXIT_REASON_XSETBV"); //$NON-NLS-1$
fExitReasonMap.put(56, "EXIT_REASON_APIC_WRITE"); //$NON-NLS-1$
fExitReasonMap.put(57, "EXIT_REASON_RDRAND"); //$NON-NLS-1$
fExitReasonMap.put(58, "EXIT_REASON_INVPCID"); //$NON-NLS-1$
fExitReasonMap.put(59, "EXIT_REASON_VMFUNC"); //$NON-NLS-1$
fExitReasonMap.put(60, "EXIT_REASON_ENCLS"); //$NON-NLS-1$
fExitReasonMap.put(61, "EXIT_REASON_RDSEED"); //$NON-NLS-1$
fExitReasonMap.put(62, "EXIT_REASON_PML_FULL"); //$NON-NLS-1$
fExitReasonMap.put(63, "EXIT_REASON_XSAVES"); //$NON-NLS-1$
fExitReasonMap.put(64, "EXIT_REASON_XRSTORS"); //$NON-NLS-1$
fExitReasonMap.put(67, "EXIT_REASON_UMWAIT"); //$NON-NLS-1$
fExitReasonMap.put(68, "EXIT_REASON_TPAUSE"); //$NON-NLS-1$
fExitReasonMap.put(74, "EXIT_REASON_BUS_LOCK"); //$NON-NLS-1$
fExitReasonMap.put(75, "EXIT_REASON_NOTIFY"); //$NON-NLS-1$
}

/**
* @param code The code of the exit type
* @return The text describing the exit type
*/
public static String getExitReasonName(int code) {
return fExitReasonMap.getOrDefault(code, "UNKNOWN_EXIT_REASON"); //$NON-NLS-1$
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*******************************************************************************
* Copyright (c) 2026 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.incubator.internal.virtual.machine.analysis.core.flow.analysis;

/**
* Represents a single event within a unified execution flow.
* <p>
* A {@code FlowEvent} wraps a {@link KernelEventInfo} and classifies it
* according to its role in the execution sequence (guest, hypervisor,
* VM transition, etc.).
* </p>
*
* @author Francois Belias
*/
public class FlowEvent {

/**
* The underlying kernel event associated with this flow event.
*/
final KernelEventInfo fKernelEvent;

/**
* The type of this flow event within the execution flow.
*/
final FlowEventType fType;

/**
* Timestamp of the corresponding guest event, used for correlating
* hypervisor events back to guest execution.
* <p>
* This value is primarily used for {@link FlowEventType#HYPERVISOR_EVENT}
* and is set to {@code -1} when not applicable.
* </p>
*/
long fCorrelatedGuestTimestamp = -1;

/**
* Constructs a {@code FlowEvent}.
*
* @param kernelEvent
* the underlying kernel event
* @param type
* the type of the flow event
*/
FlowEvent(KernelEventInfo kernelEvent, FlowEventType type) {
this.fKernelEvent = kernelEvent;
this.fType = type;
}
}


/**
* Enumerates the different types of events in a unified execution flow.
* <p>
* These types describe the role of each event in the interaction between
* guest execution and hypervisor activity.
* </p>
*/
enum FlowEventType {

/**
* A regular event occurring in the guest (virtual machine).
*/
GUEST_EVENT,

/**
* A VM exit event, marking the transition from guest to hypervisor.
*/
VM_EXIT,

/**
* An event occurring in the hypervisor (host) while handling a VM exit.
*/
HYPERVISOR_EVENT,

/**
* A VM entry event, marking the transition from hypervisor back to guest.
*/
VM_ENTRY,

/**
* An event occurring in a native (non-virtualized) environment.
*/
NATIVE
}
Loading
Loading