On Thu, 11 Jul 2019, Alexandre Chartre wrote: > +/* > + * When isolation is active, the address space doesn't necessarily map > + * the percpu offset value (this_cpu_off) which is used to get pointers > + * to percpu variables. So functions which can be invoked while isolation > + * is active shouldn't be getting pointers to percpu variables (i.e. with > + * get_cpu_var() or this_cpu_ptr()). Instead percpu variable should be > + * directly read or written to (i.e. with this_cpu_read() or > + * this_cpu_write()). > + */ > + > +int asi_enter(struct asi *asi) > +{ > + enum asi_session_state state; > + struct asi *current_asi; > + struct asi_session *asi_session; > + > + state = this_cpu_read(cpu_asi_session.state); > + /* > + * We can re-enter isolation, but only with the same ASI (we don't > + * support nesting isolation). Also, if isolation is still active, > + * then we should be re-entering with the same task. > + */ > + if (state == ASI_SESSION_STATE_ACTIVE) { > + current_asi = this_cpu_read(cpu_asi_session.asi); > + if (current_asi != asi) { > + WARN_ON(1); > + return -EBUSY; > + } > + WARN_ON(this_cpu_read(cpu_asi_session.task) != current); > + return 0; > + } > + > + /* isolation is not active so we can safely access the percpu pointer */ > + asi_session = &get_cpu_var(cpu_asi_session);
get_cpu_var()?? Where is the matching put_cpu_var() ? get_cpu_var() contains a preempt_disable ... What's wrong with a simple this_cpu_ptr() here? > +void asi_exit(struct asi *asi) > +{ > + struct asi_session *asi_session; > + enum asi_session_state asi_state; > + unsigned long original_cr3; > + > + asi_state = this_cpu_read(cpu_asi_session.state); > + if (asi_state == ASI_SESSION_STATE_INACTIVE) > + return; > + > + /* TODO: Kick sibling hyperthread before switching to kernel cr3 */ > + original_cr3 = this_cpu_read(cpu_asi_session.original_cr3); > + if (original_cr3) Why would this be 0 if the session is active? > + write_cr3(original_cr3); > + > + /* page-table was switched, we can now access the percpu pointer */ > + asi_session = &get_cpu_var(cpu_asi_session); See above. > + WARN_ON(asi_session->task != current); > + asi_session->state = ASI_SESSION_STATE_INACTIVE; > + asi_session->asi = NULL; > + asi_session->task = NULL; > + asi_session->original_cr3 = 0; > +} Thanks, tglx