@@ -360,29 +360,6 @@ static int its_sync_lpi_pending_table(struct kvm_vcpu *vcpu)
360360 return ret ;
361361}
362362
363- static unsigned long vgic_mmio_read_its_ctlr (struct kvm * vcpu ,
364- struct vgic_its * its ,
365- gpa_t addr , unsigned int len )
366- {
367- u32 reg = 0 ;
368-
369- mutex_lock (& its -> cmd_lock );
370- if (its -> creadr == its -> cwriter )
371- reg |= GITS_CTLR_QUIESCENT ;
372- if (its -> enabled )
373- reg |= GITS_CTLR_ENABLE ;
374- mutex_unlock (& its -> cmd_lock );
375-
376- return reg ;
377- }
378-
379- static void vgic_mmio_write_its_ctlr (struct kvm * kvm , struct vgic_its * its ,
380- gpa_t addr , unsigned int len ,
381- unsigned long val )
382- {
383- its -> enabled = !!(val & GITS_CTLR_ENABLE );
384- }
385-
386363static unsigned long vgic_mmio_read_its_typer (struct kvm * kvm ,
387364 struct vgic_its * its ,
388365 gpa_t addr , unsigned int len )
@@ -1161,33 +1138,16 @@ static void vgic_mmio_write_its_cbaser(struct kvm *kvm, struct vgic_its *its,
11611138#define ITS_CMD_SIZE 32
11621139#define ITS_CMD_OFFSET (reg ) ((reg) & GENMASK(19, 5))
11631140
1164- /*
1165- * By writing to CWRITER the guest announces new commands to be processed.
1166- * To avoid any races in the first place, we take the its_cmd lock, which
1167- * protects our ring buffer variables, so that there is only one user
1168- * per ITS handling commands at a given time.
1169- */
1170- static void vgic_mmio_write_its_cwriter (struct kvm * kvm , struct vgic_its * its ,
1171- gpa_t addr , unsigned int len ,
1172- unsigned long val )
1141+ /* Must be called with the cmd_lock held. */
1142+ static void vgic_its_process_commands (struct kvm * kvm , struct vgic_its * its )
11731143{
11741144 gpa_t cbaser ;
11751145 u64 cmd_buf [4 ];
1176- u32 reg ;
11771146
1178- if (!its )
1179- return ;
1180-
1181- mutex_lock (& its -> cmd_lock );
1182-
1183- reg = update_64bit_reg (its -> cwriter , addr & 7 , len , val );
1184- reg = ITS_CMD_OFFSET (reg );
1185- if (reg >= ITS_CMD_BUFFER_SIZE (its -> cbaser )) {
1186- mutex_unlock (& its -> cmd_lock );
1147+ /* Commands are only processed when the ITS is enabled. */
1148+ if (!its -> enabled )
11871149 return ;
1188- }
11891150
1190- its -> cwriter = reg ;
11911151 cbaser = CBASER_ADDRESS (its -> cbaser );
11921152
11931153 while (its -> cwriter != its -> creadr ) {
@@ -1207,6 +1167,34 @@ static void vgic_mmio_write_its_cwriter(struct kvm *kvm, struct vgic_its *its,
12071167 if (its -> creadr == ITS_CMD_BUFFER_SIZE (its -> cbaser ))
12081168 its -> creadr = 0 ;
12091169 }
1170+ }
1171+
1172+ /*
1173+ * By writing to CWRITER the guest announces new commands to be processed.
1174+ * To avoid any races in the first place, we take the its_cmd lock, which
1175+ * protects our ring buffer variables, so that there is only one user
1176+ * per ITS handling commands at a given time.
1177+ */
1178+ static void vgic_mmio_write_its_cwriter (struct kvm * kvm , struct vgic_its * its ,
1179+ gpa_t addr , unsigned int len ,
1180+ unsigned long val )
1181+ {
1182+ u64 reg ;
1183+
1184+ if (!its )
1185+ return ;
1186+
1187+ mutex_lock (& its -> cmd_lock );
1188+
1189+ reg = update_64bit_reg (its -> cwriter , addr & 7 , len , val );
1190+ reg = ITS_CMD_OFFSET (reg );
1191+ if (reg >= ITS_CMD_BUFFER_SIZE (its -> cbaser )) {
1192+ mutex_unlock (& its -> cmd_lock );
1193+ return ;
1194+ }
1195+ its -> cwriter = reg ;
1196+
1197+ vgic_its_process_commands (kvm , its );
12101198
12111199 mutex_unlock (& its -> cmd_lock );
12121200}
@@ -1287,6 +1275,39 @@ static void vgic_mmio_write_its_baser(struct kvm *kvm,
12871275 * regptr = reg ;
12881276}
12891277
1278+ static unsigned long vgic_mmio_read_its_ctlr (struct kvm * vcpu ,
1279+ struct vgic_its * its ,
1280+ gpa_t addr , unsigned int len )
1281+ {
1282+ u32 reg = 0 ;
1283+
1284+ mutex_lock (& its -> cmd_lock );
1285+ if (its -> creadr == its -> cwriter )
1286+ reg |= GITS_CTLR_QUIESCENT ;
1287+ if (its -> enabled )
1288+ reg |= GITS_CTLR_ENABLE ;
1289+ mutex_unlock (& its -> cmd_lock );
1290+
1291+ return reg ;
1292+ }
1293+
1294+ static void vgic_mmio_write_its_ctlr (struct kvm * kvm , struct vgic_its * its ,
1295+ gpa_t addr , unsigned int len ,
1296+ unsigned long val )
1297+ {
1298+ mutex_lock (& its -> cmd_lock );
1299+
1300+ its -> enabled = !!(val & GITS_CTLR_ENABLE );
1301+
1302+ /*
1303+ * Try to process any pending commands. This function bails out early
1304+ * if the ITS is disabled or no commands have been queued.
1305+ */
1306+ vgic_its_process_commands (kvm , its );
1307+
1308+ mutex_unlock (& its -> cmd_lock );
1309+ }
1310+
12901311#define REGISTER_ITS_DESC (off , rd , wr , length , acc ) \
12911312{ \
12921313 .reg_offset = off, \
0 commit comments